Chemical Equilibrium

Every reaction is secretly two reactions running in opposite directions. Equilibrium is the point where they tie. Once you can write down an equilibrium constant, read an ICE table, and apply Le Chatelier's principle, a huge slice of chemistry stops feeling like magic and starts feeling like bookkeeping.

Prereq: logs and exponents, stoichiometry Read time: ~35 min Interactive figures: 1 Code: NumPy, Python

1. Why equilibrium matters

You dissolve an aspirin tablet in water. Some of it dissociates into ions, some stays intact. You add a drop of acid to a buffer and the pH barely moves. A pharmaceutical company spends years tuning a synthesis so that an expensive precursor actually converts into product instead of sitting around unreacted. A cement kiln burns limestone to make quicklime, and the industrial engineers care intensely about the exact temperature because it decides how far the reaction runs. Your blood holds its pH at 7.4 within a hundredth of a unit even while you exercise and dump CO2 into it.

Every one of those stories is the same story: a reaction that goes forward and backward at the same time, and the balance between the two directions decides what you end up with. That balance is chemical equilibrium. It is not "the reaction stopped." The reaction never stops. At equilibrium, forward and reverse are running at identical rates, so the net concentrations sit still. It's dynamic, not dead.

THE PUNCHLINE

For a reversible reaction, there exists a single number — the equilibrium constant $K$ — that tells you the ratio of products to reactants at equilibrium, at a given temperature. If you know $K$, you can predict how much of each species will be around once things settle. That one number replaces a huge amount of case-by-case reasoning.

Why should you care, whether you build drugs, batteries, fertilizers, fuel cells, climate models, or just drink coffee in the morning? A few reasons in increasing order of how directly they touch your day job:

This page will teach you equilibrium from zero. You need to remember what moles and molarity mean, and how to read a balanced equation. Everything else we will build.

2. Vocabulary cheat sheet

Glance at this table now. Each symbol gets a full treatment below.

SymbolRead asMeans
$K$ or $K_{eq}$"K-eq"Equilibrium constant. The ratio of products to reactants (each raised to its stoichiometric coefficient) at equilibrium.
$K_c$"K-c"Equilibrium constant written in terms of molar concentrations (M).
$K_p$"K-p"Equilibrium constant written in terms of partial pressures (atm or bar).
$Q$"Q"Reaction quotient — same formula as $K$ but with current, not equilibrium, concentrations.
$K_a, K_b$"K-a, K-b"Acid and base ionization constants. Measure how far a weak acid or base dissociates.
$K_w$"K-w"Ion product of water: $[H^+][OH^-] = 10^{-14}$ at 25°C.
$K_{sp}$"K-s-p"Solubility product. An equilibrium constant for a solid dissolving into its ions.
$K_f$"K-f"Formation constant for a complex ion.
pH"p-H"$-\log_{10}[H^+]$. A compact way to write hydrogen-ion concentration.
$[\text{X}]$"concentration of X"Molar concentration of species X, in moles per liter.

One convention warning before we start: concentrations are dimensionless in the formal definition of $K$ (they're implicitly divided by a 1 M reference state), which is why $K$ comes out as a pure number. In practice you just write $[\text{A}]$ in molarity and don't worry about the units — they cancel out if you're careful.

3. The equilibrium constant

Consider a generic reversible reaction:

$$ aA + bB \; \rightleftharpoons \; cC + dD. $$

A generic reversible reaction

$A, B$
Reactants — the molecules you start with.
$C, D$
Products — the molecules formed.
$a, b, c, d$
Stoichiometric coefficients — how many of each species appear in the balanced equation. For $2 H_2 + O_2 \to 2 H_2O$, these are 2, 1, and 2.
$\rightleftharpoons$
"Reversible arrow." The reaction can run both ways. Crucially different from a single $\to$, which implies one-way.

Picture. Imagine two buckets — one on the left, one on the right — connected by two pipes. One pipe pumps water right (forward reaction), the other pumps water left (reverse). At equilibrium, both pumps are still running, but the water levels stop changing.

At equilibrium, the law of mass action says the concentrations obey:

$$ K_c \;=\; \frac{[C]^c \, [D]^d}{[A]^a \, [B]^b}. $$

The equilibrium constant expression

$K_c$
Equilibrium constant in terms of concentrations. Depends only on temperature — not on how you started, or how much you have, or the vessel size.
$[C], [D]$
Molar concentrations of the products at equilibrium, in mol/L.
$[A], [B]$
Molar concentrations of the reactants at equilibrium.
$[C]^c$
Concentration of $C$ raised to the power of its stoichiometric coefficient $c$. The coefficient is the exponent — this is the most commonly muffed detail on first exposure.
products / reactants
Products always go in the numerator. If you flip the reaction, you flip $K$ (new $K$ = $1/$old $K$).

Why coefficients become exponents. The derivation from kinetics: forward rate is proportional to $[A]^a [B]^b$, reverse rate is proportional to $[C]^c [D]^d$, and at equilibrium they're equal. Set them equal, solve for the ratio, and exponents fall out naturally. Thermodynamically, the same expression pops out of the condition $\Delta G = 0$ at equilibrium.

A concrete example: the Haber process, which makes nearly all of the world's fertilizer nitrogen:

$$ N_2(g) + 3\,H_2(g) \; \rightleftharpoons \; 2\,NH_3(g), \qquad K_c \approx 6.0 \times 10^{-2} \text{ at } 500\text{°C}. $$

Haber process equilibrium

$N_2(g)$
Nitrogen gas, the cheap feedstock from air.
$3\,H_2(g)$
Three moles of hydrogen gas per mole of nitrogen. The 3 becomes an exponent in $K$.
$2\,NH_3(g)$
Two moles of ammonia per mole of nitrogen. The 2 becomes an exponent.
$K_c \approx 0.06$
At high temperature, $K$ is small — the reaction favors reactants. Which is why industry runs it at high pressure and moderate temperature: pressure pushes the equilibrium toward fewer gas moles (ammonia side) even when the raw $K$ is small.

Why this matters. Fritz Haber figured this out around 1909, and it roughly doubled the food supply of the planet. The trade-off between rate (which wants high temperature) and yield (which wants low temperature, because the reaction is exothermic) is a classic equilibrium problem — and it's solved by running at a hot-but-not-too-hot temperature with an iron catalyst and roughly 200 atm of pressure.

Gases: $K_p$ vs $K_c$

When your species are gases, you can use partial pressures instead of concentrations:

$$ K_p \;=\; \frac{P_C^c \, P_D^d}{P_A^a \, P_B^b}. $$

Equilibrium in partial pressures

$K_p$
Equilibrium constant using partial pressures.
$P_A$
Partial pressure of gas $A$ — its contribution to the total pressure, typically in atm or bar.
$c, d, a, b$
Same stoichiometric coefficients as before.

Link to $K_c$. Since $P = nRT/V = [X]RT$ for each gas, you can convert: $K_p = K_c \, (RT)^{\Delta n}$, where $\Delta n$ is the change in moles of gas going from reactants to products. For the Haber reaction, $\Delta n = 2 - (1+3) = -2$, and $K_p$ is related to $K_c$ through a factor of $(RT)^{-2}$.

What doesn't go in the expression

Pure solids and pure liquids don't appear in $K$ expressions. Their "concentration" is a constant — they have a fixed density — so the usual convention is to fold those constants into $K$ itself. Example: for limestone decomposition

$$ CaCO_3(s) \; \rightleftharpoons \; CaO(s) + CO_2(g), \quad K_p = P_{CO_2}. $$

Pure phases drop out

$CaCO_3(s), CaO(s)$
Limestone and quicklime — both solids. Solids don't appear in $K$ because their activity is 1.
$CO_2(g)$
The only gas-phase species, so it's the only thing in the expression.
$K_p = P_{CO_2}$
At fixed temperature, there's a single equilibrium $CO_2$ pressure above a mixture of the two solids. You could turn this into a $CO_2$ thermometer if you wanted.

Why it works. Cement kilns exploit this: above about 825°C, the equilibrium $CO_2$ pressure exceeds 1 atm, so carbonate breaks down and stays broken down. Below that temperature the reverse happens and quicklime reabsorbs $CO_2$ from air. The temperature that makes $K_p = 1$ atm is the practical "go" point.

4. The reaction quotient $Q$ — which way does it go?

$K$ tells you the ratio at equilibrium. But what if you mix some $A$, $B$, $C$, and $D$ together and want to know which way the reaction will run? That's what $Q$ is for. $Q$ has the same formula as $K$, but you plug in the current concentrations, not the equilibrium ones:

$$ Q \;=\; \frac{[C]^c \, [D]^d}{[A]^a \, [B]^b}, \quad \text{(using current concentrations, not necessarily equilibrium).} $$

Reaction quotient

$Q$
A snapshot of the product/reactant ratio at any instant. Only equals $K$ when you're at equilibrium.
Current concentrations
Whatever you just mixed up, or wherever the reaction currently is — not the equilibrium values.

Rules of the road. If $Q < K$, you have too few products, so net reaction runs forward (left to right) to raise $Q$ toward $K$. If $Q > K$, too many products, so net reaction runs reverse. If $Q = K$, you're already at equilibrium and nothing net happens.

This is genuinely useful. Imagine you have a reaction vessel with $[A] = 0.5$ M, $[B] = 0.5$ M, and $[C] = 1.0$ M for $A + B \rightleftharpoons C$ with $K_c = 2$. Compute $Q = 1.0 / (0.5 \cdot 0.5) = 4.0$. Since $4 > 2$, the system has too many products. Net reverse. You'll watch $[C]$ drop and $[A], [B]$ rise until $Q$ hits 2.

5. Le Chatelier's principle

Here's a rule that looks like magic and is actually just $Q$-vs-$K$ logic in plain English.

Le Chatelier's principle. If an equilibrium is disturbed — by adding or removing something, changing the volume, or changing the temperature — the system will shift in the direction that partially undoes the disturbance.

The principle sounds almost like personality advice, and it is often taught as a handwave. But every case is just "what did the disturbance do to $Q$, and what does that imply about direction?"

The temperature dependence is quantified by the van't Hoff equation, which is essentially the Clausius-Clapeyron relation applied to $K$:

$$ \ln\!\left(\frac{K_2}{K_1}\right) \;=\; -\frac{\Delta H^\circ}{R}\!\left(\frac{1}{T_2} - \frac{1}{T_1}\right). $$

van't Hoff equation

$K_1, K_2$
Equilibrium constants at temperatures $T_1$ and $T_2$ (in kelvin, always).
$\Delta H^\circ$
Standard enthalpy of reaction — how much heat the forward reaction releases (negative) or absorbs (positive), per mole, in J/mol or kJ/mol.
$R$
The ideal gas constant, $8.314$ J/(mol·K). Just a units conversion factor.
$\ln(K_2/K_1)$
How $K$ changes on a log scale — because rate- and equilibrium-type quantities are multiplicatively sensitive to temperature.

How to read it. For an exothermic reaction ($\Delta H < 0$), if $T_2 > T_1$ then $(1/T_2 - 1/T_1) < 0$, and the right-hand side is negative, so $K_2 < K_1$. Higher temperature, lower $K$, shifted backward. Exactly the qualitative Le Chatelier rule, but with a number attached.

6. ICE tables — the algebra machine for equilibrium

Most equilibrium problems reduce to this question: "I start with these amounts, and I know $K$. What are the concentrations at equilibrium?" The universal solving technique is the ICE table. ICE stands for Initial, Change, Equilibrium. Make three rows, fill them in, and your unknowns line up on a silver platter.

Example. Consider $N_2O_4(g) \rightleftharpoons 2 NO_2(g)$ with $K_c = 4.6 \times 10^{-3}$ at 25°C. You start with $[N_2O_4]_0 = 0.10$ M and no $NO_2$. Find the equilibrium concentrations.

$N_2O_4$$NO_2$
Initial0.100
Change$-x$$+2x$
Equilibrium$0.10 - x$$2x$

The change row reflects the stoichiometry: for every $x$ moles per liter of $N_2O_4$ that disappear, $2x$ moles per liter of $NO_2$ appear (coefficient of 2). Now plug equilibrium values into the $K$ expression:

$$ K_c \;=\; \frac{[NO_2]^2}{[N_2O_4]} \;=\; \frac{(2x)^2}{0.10 - x} \;=\; 4.6 \times 10^{-3}. $$

Plug ICE into K

$(2x)^2$
Equilibrium $[NO_2]$ squared — because the coefficient of $NO_2$ is 2, it gets that exponent in the $K$ expression.
$0.10 - x$
Equilibrium $[N_2O_4]$ — what's left after $x$ mol/L converted.
$4.6 \times 10^{-3}$
The given $K$.

Small-$x$ approximation. When $K$ is much smaller than the initial concentration (here $4.6 \times 10^{-3} \ll 0.10$), you can often assume $x \ll 0.10$ and approximate $0.10 - x \approx 0.10$. That gives $4 x^2 / 0.10 = 4.6 \times 10^{-3}$, so $x^2 = 1.15 \times 10^{-4}$, and $x \approx 0.0107$. Check: $0.0107 / 0.10 \approx 11\%$ — borderline, but the approximation is usable. Rule of thumb: if $x$ is less than 5% of the initial, you're fine; if 5-10%, quote both approximation and exact answer; beyond 10%, solve the quadratic.

Solving exactly: $(2x)^2 = 4.6 \times 10^{-3} (0.10 - x)$ gives $4x^2 + 4.6 \times 10^{-3} x - 4.6 \times 10^{-4} = 0$. Quadratic formula gives $x \approx 0.0102$ M. So at equilibrium, $[N_2O_4] \approx 0.090$ M and $[NO_2] \approx 0.020$ M. About 10% of the $N_2O_4$ dissociated — which is why you see brown $NO_2$ in a flask that was initially colorless $N_2O_4$.

7. Acid-base equilibria

Acid-base chemistry is just equilibrium chemistry applied to proton transfers. The two big constants are $K_a$ (how strongly an acid gives up its proton) and $K_b$ (how strongly a base grabs one).

$$ HA(aq) + H_2O(l) \; \rightleftharpoons \; H_3O^+(aq) + A^-(aq), \quad K_a \;=\; \frac{[H_3O^+][A^-]}{[HA]}. $$

Acid ionization

$HA$
A generic weak acid. $H$ is the proton to donate, $A$ is the conjugate base.
$H_3O^+$
Hydronium ion — a water molecule that has accepted a proton. Usually we just write $H^+$ for short, but hydronium is the physically real species in water.
$A^-$
The deprotonated acid — the conjugate base of $HA$.
$K_a$
Acid dissociation constant. Bigger $K_a$ = stronger acid. For acetic acid, $K_a \approx 1.8 \times 10^{-5}$. For HCl, $K_a \approx 10^{6}$ (essentially fully dissociated — we call it a strong acid).
$H_2O$
Water, the solvent. Its "concentration" (55 M) is folded into $K_a$ by convention, so it doesn't appear in the expression.

Why log scales. $K_a$ values span 30 orders of magnitude across common acids. Nobody wants to type "0.00000018" every time, so chemists use $pK_a = -\log_{10} K_a$. Acetic acid's $pK_a$ is $4.76$. Carbonic acid's is $6.35$. Water itself has $pK_a \approx 15.7$. Smaller $pK_a$ = stronger acid. The whole pH scale is a log scale for exactly the same reason.

pH, pOH, and $K_w$

Pure water autoionizes a little bit: $H_2O + H_2O \rightleftharpoons H_3O^+ + OH^-$. The equilibrium constant for this is

$$ K_w \;=\; [H^+][OH^-] \;=\; 1.0 \times 10^{-14} \text{ at 25°C}. $$

The ion product of water

$K_w$
A fundamental constant of aqueous chemistry. At 25°C it's exactly $10^{-14}$ (close enough to exactly that chemists quote it as such).
$[H^+]$
Hydronium concentration. In pure water, $\sqrt{10^{-14}} = 10^{-7}$ M.
$[OH^-]$
Hydroxide concentration. Same thing in pure water.

Why pH 7 is "neutral." Because $\log_{10}(10^{-7}) = -7$, and $pH = -\log[H^+] = 7$. That 7 is not special — it's just the square root of $K_w$ turned into a log. At body temperature (37°C), $K_w$ rises slightly and neutral pH drops to about 6.8. Cold seawater has neutral around 7.5.

Define $pH = -\log_{10}[H^+]$ and $pOH = -\log_{10}[OH^-]$. Taking $-\log$ of both sides of $K_w$:

$$ pH + pOH \;=\; 14 \quad (\text{at 25°C}). $$

pH and pOH are complementary

$pH$
Negative base-10 log of hydronium concentration. Low pH = acidic, high pH = basic, 7 is neutral at 25°C.
$pOH$
Same for hydroxide.
$14$
The value of $-\log_{10}(K_w) = -\log_{10}(10^{-14})$.

Useful shortcut. If you know one, you know the other. pH 3 coffee has pOH 11. pH 9 soap has pOH 5. Blood (pH 7.4) has pOH 6.6.

Henderson-Hasselbalch and buffers

Rearrange the $K_a$ expression by taking $-\log$ of both sides:

$$ pH \;=\; pK_a + \log_{10}\!\left(\frac{[A^-]}{[HA]}\right). $$

Henderson-Hasselbalch equation

$pH$
The pH of the solution you're designing.
$pK_a$
$-\log_{10}(K_a)$ for the weak acid in the buffer. The buffer works best when $pH \approx pK_a$, i.e. when the ratio on the right is about 1.
$[A^-]/[HA]$
The ratio of conjugate base to acid form. You control this by how much of each you add.

Why buffers resist pH changes. If you add a little strong acid, some $A^-$ converts to $HA$. The ratio shifts only slightly (as long as both forms are plentiful), so $\log$ of the ratio moves even less, and pH moves by a tiny amount. That's why blood uses the $H_2CO_3 / HCO_3^-$ system with $pK_a \approx 6.35$, and why the body tolerates enormous loads of metabolic acid without the pH shifting more than a few hundredths. Design rule: pick a buffer acid with $pK_a$ close to your target pH, within about $\pm 1$.

Worked example. You want a buffer at pH 4.8 using acetic acid ($pK_a = 4.76$). Then $\log([A^-]/[HA]) = 4.8 - 4.76 = 0.04$, so $[A^-]/[HA] = 10^{0.04} \approx 1.10$. You need 1.10 moles of sodium acetate per mole of acetic acid. If you mix 0.100 mol acetic acid with 0.110 mol sodium acetate in 1 L of water, you have a pH 4.8 buffer that will hold its pH against modest acid/base additions.

8. Interactive: titration curve plotter

A titration is: you have a weak acid of known concentration, you add strong base slowly, and you watch the pH. The curve has four interesting features — the initial pH, the buffer region near $pH = pK_a$, the steep equivalence point, and the final plateau. Slide $pK_a$ and see how the curve morphs; slide the initial acid concentration and watch the equivalence-point pH rise.

pK_a: 4.76 [HA]₀ (M): 0.100

Titrate 50.0 mL of a weak acid with 0.100 M NaOH. Curve flattens in the buffer region ($pH \approx pK_a$), then jumps at the equivalence point (half-equivalence marked with the pink dot).

Things to look for as you drag:

9. Solubility equilibria — $K_{sp}$

Insoluble salts aren't totally insoluble. A tiny amount dissolves, and the dissolved fraction sits at equilibrium with the solid. For $AgCl(s) \rightleftharpoons Ag^+(aq) + Cl^-(aq)$:

$$ K_{sp} \;=\; [Ag^+][Cl^-] \;=\; 1.8 \times 10^{-10}. $$

Solubility product

$K_{sp}$
Solubility product. The product of ion concentrations at saturation. The solid itself (pure phase) doesn't appear.
$[Ag^+]$
Silver ion concentration at saturation.
$[Cl^-]$
Chloride ion concentration at saturation.

Molar solubility. If you drop $AgCl$ into pure water, $[Ag^+] = [Cl^-] = s$ where $s$ is the molar solubility. So $s^2 = K_{sp}$, giving $s = \sqrt{1.8 \times 10^{-10}} \approx 1.3 \times 10^{-5}$ M — about 2 mg per liter. Silver halides are used in photographic film because they're essentially insoluble but photosensitive. For a salt like $Ca_3(PO_4)_2$ (bone mineral), $K_{sp} = [Ca^{2+}]^3 [PO_4^{3-}]^2$ — the stoichiometric coefficients become exponents, just like the generic $K$.

Common-ion effect

Add a source of $Cl^-$ to that silver chloride solution — say, sodium chloride at 0.10 M. Now $[Cl^-]$ is fixed at 0.10, so $[Ag^+]$ has to shrink to $K_{sp} / 0.10 = 1.8 \times 10^{-9}$ M to maintain the product. The silver chloride is less soluble in salt water than in pure water. This is the common-ion effect. It's Le Chatelier's principle applied to dissolution: you added a product, so the equilibrium shifts toward the solid.

Practical use: in water treatment, adding excess phosphate precipitates out calcium. In kidney-stone pathology, a high-oxalate diet raises $[C_2O_4^{2-}]$ and shifts $CaC_2O_4$ out of solution inside your kidneys. The same math, different context.

Prediction rule. If you mix ionic solutions and wonder whether a precipitate will form, compute $Q_{sp}$ from the initial concentrations. If $Q_{sp} > K_{sp}$, precipitation will occur until $Q$ drops to $K$. If $Q_{sp} < K_{sp}$, nothing precipitates — the solution is undersaturated.

10. Complex-ion equilibria

Transition metal cations love to grab ligands — small molecules or anions that donate electron pairs to the metal. The equilibrium constant for complex formation is $K_f$:

$$ Ag^+(aq) + 2\,NH_3(aq) \; \rightleftharpoons \; [Ag(NH_3)_2]^+(aq), \quad K_f = 1.7 \times 10^{7}. $$

Formation constant

$Ag^+$
A bare silver cation — the metal center.
$NH_3$
Ammonia, a two-electron donor. It's acting as a ligand here.
$[Ag(NH_3)_2]^+$
The diamminesilver(I) complex — the final, solvated species.
$K_f$
Formation constant, which is the equilibrium constant for the complex formation written as products-over-reactants. Very big $K_f$ means the complex is strongly favored.

Why this matters. Silver halides are "insoluble" — but if you add ammonia, the $Ag^+$ gets grabbed by $NH_3$, pulling it out of the dissolution equilibrium. $[Ag^+]$ drops, so the $K_{sp}$ equilibrium shifts dissolution-ward, so more $AgCl$ dissolves. This is exactly how you redissolve silver chloride in chemistry labs, and how historical photographers "fixed" silver halide films using thiosulfate (which forms $[Ag(S_2O_3)_2]^{3-}$, an even more stable complex).

Biological ligands work the same way. Heme in hemoglobin is an $Fe^{2+}$ porphyrin complex. $O_2$ binding to heme is a complex-formation equilibrium with a $K_f$ that's sharply tuned by surrounding protein to grab oxygen in lungs and release it in tissues. Carbon monoxide poisoning is this equilibrium with a far larger $K_f$ for CO than for $O_2$ — CO wins the binding competition irreversibly.

11. Equilibrium in code

Three small routines: solving for $x$ in an ICE table using the quadratic formula, computing pH of a weak acid, and simulating a titration curve.

equilibrium primitives
import numpy as np

# ---------- 1. Solve (2x)^2 / (C0 - x) = K for x, via quadratic ----------
def ice_solve_dissociation(C0, K):
    # N2O4 -> 2 NO2 style: 4 x^2 + K x - K C0 = 0
    a, b, c = 4.0, K, -K * C0
    disc = b * b - 4 * a * c
    x = (-b + np.sqrt(disc)) / (2 * a)
    return x

# Sanity check against worked example in the text
x = ice_solve_dissociation(0.10, 4.6e-3)
print(f"x = {x:.5f} M,  [N2O4] = {0.10 - x:.4f},  [NO2] = {2*x:.4f}")

# ---------- 2. pH of a weak acid at concentration C, given Ka ----------
def weak_acid_pH(C, Ka):
    # HA -> H+ + A-,  K = x^2 / (C - x)
    # x^2 + K x - K C = 0
    disc = Ka * Ka + 4 * Ka * C
    x = (-Ka + np.sqrt(disc)) / 2
    return -np.log10(x)

print(f"pH of 0.10 M acetic acid: {weak_acid_pH(0.10, 1.8e-5):.2f}")
# Expected: ~2.87

# ---------- 3. Titration curve: weak acid + strong base ----------
def titration_curve(C_HA, V_HA, C_NaOH, pKa, V_base):
    # V_base is an array of NaOH volumes added (mL).
    # Returns pH at each volume.
    Ka = 10 ** (-pKa)
    n_HA = C_HA * V_HA / 1000                      # moles of acid
    n_OH = C_NaOH * V_base / 1000                   # moles base added
    V_tot = (V_HA + V_base) / 1000                    # total volume L

    pH = np.zeros_like(V_base, dtype=float)
    for i, (nb, V) in enumerate(zip(n_OH, V_tot)):
        if nb < n_HA:
            # Buffer region: Henderson-Hasselbalch
            nHA = n_HA - nb
            nA  = nb
            pH[i] = pKa + np.log10(max(nA, 1e-12) / max(nHA, 1e-12))
        elif np.isclose(nb, n_HA):
            # Equivalence: pure A- hydrolysis, pH > 7
            C_A = n_HA / V
            Kb  = 1e-14 / Ka
            x   = np.sqrt(Kb * C_A)
            pH[i] = 14 + np.log10(max(x, 1e-14))
        else:
            # Excess strong base
            C_OH = (nb - n_HA) / V
            pH[i] = 14 + np.log10(C_OH)
    return pH

V = np.linspace(0.1, 100, 200)
curve = titration_curve(0.10, 50, 0.10, 4.76, V)
print("half-equiv pH =", float(curve[49]))     # ~ pKa = 4.76
import math

# Same ideas, plain Python.

def pH_weak_acid(C, Ka):
    disc = Ka * Ka + 4 * Ka * C
    x = (-Ka + math.sqrt(disc)) / 2
    return -math.log10(x)

def pH_buffer(pKa, ratio_A_to_HA):
    return pKa + math.log10(ratio_A_to_HA)

def ksp_molar_solubility(Ksp, n_cation, n_anion):
    # e.g. Ca3(PO4)2: n_cat=3, n_an=2
    # Ksp = (n_cat s)^n_cat * (n_an s)^n_an
    prefactor = (n_cation ** n_cation) * (n_anion ** n_anion)
    total_order = n_cation + n_anion
    return (Ksp / prefactor) ** (1 / total_order)

print(f"0.10 M acetic pH: {pH_weak_acid(0.10, 1.8e-5):.2f}")
print(f"pH 4.8 buffer ratio: {pH_buffer(4.76, 1.10):.3f}")
print(f"Ca3(PO4)2 solubility: {ksp_molar_solubility(2e-29, 3, 2):.2e} M")

A few practical notes:

12. Cheat sheet

Equilibrium constant

$K = \dfrac{[C]^c[D]^d}{[A]^a[B]^b}$

Products over reactants, each to its stoichiometric power.

Reaction quotient

Same formula as $K$ with current concentrations

$Q < K$ forward. $Q > K$ reverse. $Q = K$ equilibrium.

$K_p$ vs $K_c$

$K_p = K_c (RT)^{\Delta n}$

$\Delta n$ = moles gas products minus moles gas reactants.

van't Hoff

$\ln(K_2/K_1) = -\dfrac{\Delta H^\circ}{R}\!\left(\dfrac{1}{T_2} - \dfrac{1}{T_1}\right)$

How $K$ changes with temperature.

$K_a$, $K_b$, $K_w$

$K_a K_b = K_w = 10^{-14}$

Conjugate pair link. True at 25°C.

pH

$pH = -\log_{10}[H^+]$

Log of hydronium. $pH + pOH = 14$.

Henderson-Hasselbalch

$pH = pK_a + \log([A^-]/[HA])$

Buffer design. Max capacity at $pH = pK_a$.

$K_{sp}$

Product of ion concentrations at saturation

$Q_{sp} > K_{sp}$ precipitates. $< $ undersaturated.

ICE method

Initial, Change, Equilibrium rows

The universal equilibrium-problem framework.

Le Chatelier

System opposes disturbances

Add reactant $\Rightarrow$ forward. Compress gases $\Rightarrow$ fewer-mole side.

See also

Biochemistry

Enzyme kinetics and metabolism are equilibrium and steady-state chemistry on top of protein scaffolds. Michaelis-Menten is literally $K$ renamed.

Organic chemistry

Many organic syntheses need equilibrium-shifting tricks — excess reagent, product removal, Le Chatelier — to push yields up.

Thermodynamics

$\Delta G^\circ = -RT \ln K$ links Gibbs free energy to equilibrium. Chemical equilibrium is thermodynamics speaking the chemist's dialect.

Calculus (logs)

Most equilibrium math is logs and exponents. If $\ln$ and $\log_{10}$ feel slippery, revisit them before tackling buffer problems.

Further reading

  • Peter Atkins and Julio de Paula — Physical Chemistry. The canonical graduate-level treatment of chemical equilibrium and thermodynamics. Chapters 6 and 7 cover everything on this page with full rigor.
  • Ira Levine — Physical Chemistry. An alternate standard with more worked examples.
  • James Butler — Ionic Equilibrium: Solubility and pH Calculations (Wiley, 1998). Old but still the clearest reference for aqueous equilibrium calculations, including polyprotic and mixed-ion systems.
  • Wikipedia — Chemical equilibrium. A surprisingly thorough article with history, derivations, and links to modern computational approaches.
  • David Parkhurst and C. A. J. Appelo — PHREEQC documentation (usgs.gov). The open-source geochemical equilibrium solver that real water-chemistry modelers use.
NEXT UP
→ Organic Chemistry

Once you can track thermodynamic equilibria, you're ready for the subject where the equilibrium is usually pushed hard by the arrow-pushing of electrons: organic reactions.