VOLUME 1, ISSUE 3 · SPRING 2025 · ORIGINAL RESEARCH
What a Buffer Is Actually Resisting
Computational study · Peer-edited by the club review board · LaTeX source · Analysis code · Raw output · Interactive model
A Formula That Stops Too Soon
Buffer capacity has a definition, and it is a good one. Van Slyke wrote it down in 1922 as the slope of a titration curve [3], building on the mass-action treatment Henderson had published fourteen years earlier [1] and the logarithmic form Hasselbalch gave it in 1917 [2]: the number of moles of strong base you must add to a litre of solution to raise its pH by one unit. Call it \(\beta\). The larger it is, the harder the solution fights.
For a single weak acid HA at total concentration \(C\) with dissociation constant \(K_a\), the charge balance after adding \(C_b\) moles per litre of sodium hydroxide reads \(C_b + [\mathrm{H}^+] = [\mathrm{OH}^-] + [\mathrm{A}^-]\), which rearranges to
$$C_b(h) \;=\; \frac{K_w}{h} \;-\; h \;+\; \frac{C K_a}{K_a + h}$$with \(h = [\mathrm{H}^+]\). Differentiate with respect to pH, remembering that \(dh/d\mathrm{pH} = -\ln(10)\,h\), and the capacity falls out whole:
$$\beta \;=\; \ln(10)\left[\frac{K_w}{h} \;+\; h \;+\; \frac{C K_a h}{(K_a + h)^2}\right]$$That is the formula. Textbooks print it, note that the middle term peaks when \(h = K_a\), state that the peak value is \(\ln(10)\,C/4\), advise you to work within one pH unit of pKa, and move on to the next chapter. Urbansky and Schock set out the full derivation and complained, in 2000, that this is exactly where most treatments stop [11]. Every one of those statements is approximately true. Three of them are not exactly true, one of them is wrong in a way that matters for real laboratory buffers, and the last one is a rule of thumb that turns out to be a full pH unit too generous.
The figure below is what the formula looks like when you draw it rather than reading it. Five buffers at the same concentration, five different dissociation constants. Each is a hill. The hills are identical in shape and height, and they slide along the pH axis with pKa. At the far edges the solvent takes over and the curves climb away.
What We Actually Did
The club has computers and people. It does not have a burette, a pH meter, a fume cupboard or anywhere to put one. So the study is arithmetic, and the arithmetic is the experiment. Nothing below was observed in a beaker. When this article says "measured", it means measured from the output of a program written by club members, in the same sense that you measure the digits of \(\pi\) by computing them.
The program does four things. It writes the full proton condition for a solution with any number of buffers in it, keeping the water terms. It inverts that condition by bisection, so that given an amount of added strong base it returns the pH to the last bit a double can hold. It differentiates the condition three separate ways so that the three answers can be compared. And it runs the carbon dioxide system twice, once stoppered and once with the lungs attached.
Nothing is approximated. There is no Henderson-Hasselbalch step anywhere in the code, no assumption that \([\mathrm{HA}] \approx C\), no dropping of the water terms, and no linearisation of the titration curve. De Levie showed in 1993 that a titration curve has a single closed form needing no approximations and no segmentation [10], and the solver here follows that spirit. Where the literature's shortcuts appear, they appear as something to check the exact answer against, never as a step in getting it. Po and Senozan catalogued where the Henderson-Hasselbalch approximation goes wrong and by how much [12]. We did not set out to reproduce their tables, and we have not checked our numbers against them line by line, but the same kind of error appears in section 3 every time the exact solver is put beside a shortcut.
The assumptions are listed in full in the script's docstring and are worth stating here too. Activities are replaced by concentrations everywhere. Equilibrium is instantaneous, which ignores how slowly carbon dioxide hydrates, slowly enough that evolution invented carbonic anhydrase about it. Dissolved CO2 and H2CO3 are lumped together, as they always are. Temperature is fixed, at 25 °C for the generic work and 37 °C for the blood work. Adding base does not change the volume.
Three Routes to One Number
A derivative computed by a program is a claim, and claims need auditing. We computed \(\beta\) three ways that share as little machinery as possible.
The first is the analytic expression above, evaluated directly. The second is a five-point central difference of \(C_b(\mathrm{pH})\), which uses the charge balance but never the derivative. The third adds a real dose of strong base to the modelled solution, re-solves the whole nonlinear equilibrium by bisection for the new pH, does the same with an equal dose of acid, and divides. That third route is a simulated titration. It never differentiates anything and never touches equation (2).
Across pH 1 to 13 the three agree. The worst relative disagreement between the analytic expression and the finite difference is 1.395×10−10, which is what you get when you subtract two nearly equal double-precision numbers. The worst disagreement with the titration route is 1.769×10−8, and that one has a known cause: it is the truncation error of a central difference taken over a step of 10−4 pH units. Shrink the step and it shrinks as the square, exactly as a central difference should.
The solver itself was checked separately. Round-tripping pH to added base and back over the range 0.5 to 14.5 returns the input to 4.7×10−13. At half neutralisation the exact pH of 0.100 M acetic acid is 4.756304 against the pKa of 4.756000 that Harned and Ehlers measured in 1932 [4], a gap of 3×10−4 that is the water term and not an error. At the equivalence point the exact answer is 8.878022 against the textbook weak-base shortcut's 8.878000.
Plain Arithmetic
Three of the results in this article can be got with a pencil. Here they are, worked.
The peak height. Set \(h = K_a\) in the buffer term. The numerator becomes \(C K_a K_a\), the denominator \((2K_a)^2 = 4K_a^2\), so the term is \(C/4\). Multiply by \(\ln 10 = 2.302585\).
computed by the program at pKa 7.000, 0.100 M = 0.05756509
difference = +4.605×10−7, which is exactly ln(10) × (10−7 + 10−7), the solvent
The half-capacity window. Write \(r = 10^{\mathrm{pKa}-\mathrm{pH}}\), so \(r = h/K_a\). The buffer term relative to its peak is \(4r/(1+r)^2\). Set that to one half and you get \(8r = (1+r)^2\), so \(r^2 - 6r + 1 = 0\), so \(r = 3 + 2\sqrt{2} = 5.828427\).
check: 4 × 5.828427 ÷ (6.828427)2 = 23.31371 ÷ 46.62742 = 0.500000
full window = 2 × 0.7655514 = 1.5311027 pH units
computed by the program at pKa 7.000 = 1.5311518, a gap of 4.9×10−5
What is left one unit out. At \(\mathrm{pH} = \mathrm{pKa} \pm 1\), \(r = 10\) or \(r = 0.1\). Either way \(4r/(1+r)^2 = 40/121\).
two units out: 400 ÷ 10201 = 0.039212, so one part in 25.5
three units out: 0.003992, one part in 250.5
The last line is the one to keep. The standard advice is to stay within one pH unit of pKa, and that advice is quietly conceding two thirds of the buffer. The honest window, the one where you still have half the strength you paid for, is 0.766 units either side.
Notes from the Table
Tuesday, first session
Solver written. Bisection on pH rather than on h, because h spans fourteen decades and pH
spans fourteen units. Round trip clean to 1e-13 straight away. Somebody asked whether we
should use Newton. We tried. It is faster and it is not always right, and the whole point of
this study is being right.
Wednesday
Peak-finder returns pH 8.0 for a pKa 3 buffer. Argued about this for twenty minutes. It is a
minimum. Blind bisection on the derivative over the whole pH range cannot tell a maximum from
a minimum, and beta has both once the water walls are in. Rewrote the finder to demand a
bracket with the derivative positive on the left and negative on the right.
Wednesday, later
With the finder fixed, pKa 5 at 0.100 M gives a peak at pH 4.99965232, not 5. We assumed a
bug. Hunted it for most of an afternoon. It is not a bug. Set d(beta)/d(pH) to zero and the
condition is −Kw/h + h + CKa h(Ka−h)/(Ka+h)3 = 0, and at h = Ka the
third term vanishes while the first two do not. The peak is exactly at pKa only when
Ka2 = Kw, which is pKa 7.000. The displacement is
−(8/(C ln10))(Ka − Kw/Ka), and the computed ratio of found to predicted is 1.0008
at pKa 5, 1.0081 at pKa 4, 1.0943 at pKa 3 where the expansion is giving up.
Thursday
pKa 2 returns nothing at all. No peak. Checked the bracket logic twice, then plotted it and
saw why: at pKa 2 the capacity of a 0.100 M buffer is smaller than the strong-acid wall it is
sitting on, so the curve falls monotonically through the buffer's own region. Six of the
twenty-two grid cases behave this way. Nobody in the room had ever seen this stated anywhere.
Friday
Blood. Gave the model pH 7.40 and pCO2 40 mmHg with the clinical apparent pK1' of 6.10 and
asked what bicarbonate it implied. It said 24.50 mmol/L. That is what a blood gas analyser
reports. Nothing was tuned. Long pause in the room.
The Buffers With No Peak
This one surprised us. Sweep pKa from 2 to 12 at two concentrations and ask the program where each buffer's capacity peaks. Six of the twenty-two answers are that it does not.
The reason is the solvent. Near pH 2 the term \(\ln(10)\,h\) is 0.0230 mol/L per pH unit and falling steeply. A 0.100 M buffer can contribute at most 0.0576 at the very top of its hill, and the hill is sitting on a slope steeper than itself. The sum has no turning point. What the buffer produces is a shoulder, a place where the descent briefly slows, and not a maximum.
Push the concentration down to 0.010 M and the same thing starts happening at pKa 3. Go the other way, to pKa 11 and 12, and it happens in mirror image against the hydroxide wall.
So a bottle labelled as a pH 2 buffer is not doing what the label implies. Most of its resistance to added base comes from the free acid already in solution, which is to say from the solvent chemistry rather than from the conjugate pair you paid for. That is not a criticism of the bottle. It works. It is a criticism of the mental picture. Good and colleagues made proximity of pKa to the working pH their first selection criterion when they designed the biological buffers still in use today [6], and this result says the criterion has teeth at the edges of the pH range as well as in the middle.
Two in One Beaker
Put two buffers in the same solution and their capacities add, because each conjugate pair takes up protons without asking the other one. That is equation (3) in the script, and it is the whole basis of the mixed buffers people actually use, and the reason a shelf of Good's buffers covers a continuous range rather than a set of isolated points [6].
Fix the total concentration at 0.100 M, split it evenly, and slide the two pKa values apart by a separation \(D\) either side of pH 7. For small \(D\) you get one peak with a flattened top. For large \(D\) you get two peaks with a valley between. Where does it change over?
Set the second derivative of the sum at the midpoint to zero. Writing \(s(u)\) for the shape of one buffer term with \(u = \mathrm{pH} - \mathrm{pKa}\), the shape is \(1/(2 + 2\cosh(u\ln 10))\), and the condition reduces to \(\cosh(\ln(10)\,D/2) = 2\). So
$$D^{*} \;=\; \frac{2\,\mathrm{arccosh}(2)}{\ln 10} \;=\; 1.143895 \text{ pH units}$$The numerical scan flips from a single central peak to a split pair between \(D = 1.1439\) and \(D = 1.2000\), bracketing that number. Below the threshold, the pair is one broad hill. Above it, two.
The engineering consequence is a trade. Measure the width over which the mixture still delivers half of what a single 0.100 M buffer manages at its own peak. A single buffer holds that for 1.531 pH units. The pair at the threshold holds it for 1.792. Push the separation to 3.0 and the width reaches 3.107, but the middle has sagged to 0.0068 against a single buffer's 0.0576, so what you have is two buffers with a hole between them rather than one wide buffer. Width is bought with height, and the exchange rate is not generous.
Real pairs behave as predicted. Acetate and the second phosphate step sit 2.442 pH units apart, well past the threshold, and the mixture sags to 42.1% of its peak in the middle. Citrate's own second and third dissociations sit 1.635 apart and sag only to 83.5%. Phosphate with tris, 0.874 apart and inside the threshold, shows no dip at all.
Blood Should Not Work
Here is the problem, stated as baldly as possible. The dominant buffer in blood plasma is the carbon dioxide system. Its apparent first dissociation constant at 37 °C and plasma ionic strength corresponds to pK1' = 6.10 [15]. Blood is held at pH 7.40. That is 1.30 pH units away from the optimum.
Section 4 gives the penalty for being 1.30 units off. Retained fraction \(4r/(1+r)^2\) with \(r = 10^{1.3} = 19.95\) comes to 0.1818. A buffer sitting that far from its own pKa keeps 18% of its strength. Blood's total carbonate is about 25.8 mmol/L, so the closed system's capacity at pH 7.4 should be, and in our model is, 2.940 mmol/L per pH unit. Whole blood measures 38.5 and plasma 16.1 mEq/L per pH [5], and Siggaard-Andersen built the clinical acid-base chart on a non-bicarbonate buffer value of about that size [7]. The carbonate system, on this accounting, is contributing almost nothing.
Something is missing from that accounting, and the missing thing is that you are breathing.
In a stoppered bottle, adding acid to a bicarbonate solution converts bicarbonate into dissolved carbon dioxide, which stays put. The total carbonate is conserved and the buffer eats itself. In a body, the dissolved carbon dioxide is removed by the lungs as fast as it appears, and pCO2 barely moves. The right boundary condition is not "total carbonate fixed". It is "dissolved carbon dioxide fixed". Rewriting the proton condition with \(S = \alpha\,p_{\mathrm{CO}_2}\) held constant gives
$$\beta_{\text{open}} \;=\; \ln(10)\left[\frac{K_w}{h} + h + \frac{K_1 S}{h} + \frac{4K_1K_2S}{h^2}\right]$$and the third term is simply \(\ln(10)\,[\mathrm{HCO}_3^-]\). Our model, given only pH 7.40, pCO2 40 mmHg and the apparent constants, produces 24.50 mmol/L of bicarbonate and 57.32 mmol/L per pH unit of capacity. Against the closed system's 2.940, that is a factor of 19.50.
Now the part that changes how the whole thing reads. The open system has no optimum. Not a broad one, not a displaced one. None. Above pH 4.506 the capacity rises without turning back, because bicarbonate at fixed pCO2 is proportional to \(1/h\). Being 1.30 units above pK1' is not a penalty in an open system. It is the reason there is so much bicarbonate in the first place.
Put a number on that. A closed carbonate system with the same 25.8 mmol/L of total carbonate, sitting exactly on its own optimum at pH 6.10, is worth 14.881 mmol/L per pH unit. The open system at pH 7.40, a full 1.30 units off that optimum, is worth 57.317. The off-optimum open system beats the on-optimum closed one by 3.85 times. To match it with an ordinary closed buffer perfectly tuned to pH 7.40 you would need 99.6 mmol/L of it, nearly four times the carbonate blood actually carries.
The vividness comes out in the dose table. Add 10 mmol/L of strong acid to a litre and re-solve the equilibrium exactly. The open system goes from 7.400 to 7.176. The closed one goes to 6.220. One of those is a bad afternoon and the other is a death certificate, and the chemistry in the bottle is identical. The only difference is whether anything is carrying the carbon dioxide away.
The Objection We Take Seriously
The strongest objection to this study is that the open system is not a buffer and calling it one is a category error.
The argument goes like this. A buffer resists pH change using only what is dissolved in it. The open carbon dioxide system resists pH change by continuously exporting matter to a reservoir of effectively infinite size. Of course it looks better. You have compared a closed box to a box with a hole in it and a pump attached, declared the second one nineteen times the buffer, and learned nothing about buffering. Worse, our own parameterisation makes the point for us: hold the pump still and the capacity collapses. What is being measured is the pump.
We think this objection is largely correct and that it improves the result rather than destroying it.
It is correct that \(\beta_{\text{open}}\) is not a property of the solution alone. It is a property of the solution plus its boundary condition, and the boundary condition is doing most of the work. Our own section 10 numbers say so plainly: let pCO2 drift by one tenth of a decade per pH unit and you lose 10% of the capacity immediately. Let it drift by 0.956 decades, which is what a cork does, and you are back to the closed value.
Where we part company with the objection is on what follows. Van Slyke's definition is a derivative of a titration curve, and a titration curve is defined by whatever is held fixed while you titrate [3]. Nothing in the definition requires the system to be closed. If it did, the definition would be unable to describe the single most important pH regulator in vertebrate physiology, and a definition with that hole in it is the wrong definition. Roos and Boron treat open-system buffering power as a legitimate quantity for exactly this reason [8], Boron makes the same case in his teaching account of intracellular pH regulation [13], and Stewart's reformulation makes pCO2 an independent variable rather than a dependent one [9].
The honest version of the finding is therefore narrower than the headline, and better. It is not that bicarbonate is a wonderful buffer. It is that bicarbonate is a mediocre buffer at pH 7.4, and that attaching it to a controlled reservoir converts a mediocre buffer into an excellent one, by a factor this model puts at 19.50 and a Monte Carlo puts at 20.16. The chemistry contributes the 2.94. The lungs contribute the other 54.38.
One further concession. Our open model holds pCO2 perfectly constant, which no lung does. That choice sets an upper bound and we have not modelled the ventilatory control loop at all. A model with realistic respiratory dynamics would give a number between our two, closer to the open value for a slow acid load and closer to the closed value for a fast one.
Where a Different Choice Would Have Changed the Answer
Five inputs go into the blood calculation and none of them is known exactly. We varied them one at a time, and then all at once.
| Quantity | Analytic or accepted | This study | Difference |
|---|---|---|---|
| Single monoprotic buffer, 0.100 M, 25 °C | |||
| Peak capacity | 0.05756463 | 0.05756509 | +8.0×10−6 rel. |
| Peak position, pKa 7.000 | pH 7.000000 | pH 7.00000000 | 0 exactly |
| Peak position, pKa 5.000 | pH 5.000000 | pH 4.99965232 | −3.477×10−4 |
| Predicted displacement, pKa 5 | −3.474×10−4 | −3.477×10−4 | ratio 1.00080 |
| Half-capacity window | 1.5311027 | 1.5311518 | +4.9×10−5 |
| Retained at pKa ± 1 | 40/121 = 0.330579 | 0.330579 | exact |
| Retained at pKa ± 2 | 400/10201 = 0.039212 | 0.039212 | exact |
| Two components, 0.100 M total | |||
| Split threshold \(D^{*}\) | 1.143895 | between 1.1439 and 1.2000 | brackets it |
| Half-width, single buffer | 1.531103 | 1.531162 | +5.9×10−5 |
| Half-width at \(D^{*}\) | no closed form | 1.792408 | – |
| Carbon dioxide system, 37 °C, pH 7.40, pCO2 40 mmHg | |||
| Bicarbonate | 24–26 mmol/L [16] | 24.50 mmol/L | inside range |
| Dissolved CO2 | 1.2 mmol/L [15] | 1.228 mmol/L | +2.3% |
| Open-system capacity | ln10 × 24 = 55.26 | 57.317 | +3.7% |
| Closed-system capacity | ~4 mEq/L per pH [16] | 2.940 | −26.5% |
| Open / closed ratio | 1 + 101.3 = 20.953 | 19.498 | −6.9% |
| Same, Monte Carlo mean | – | 20.162 ± 0.003 | sd 1.213 |
| Open off-optimum vs closed on-optimum | – | 3.85× | – |
The sensitivity run says which choices matter. Moving pK1' from 6.10 to 6.03 takes the ratio from 19.498 to 22.461. Moving pH from 7.40 to 7.25 takes it to 14.585. Those two dominate everything else, which is what the approximation \(1 + 10^{\mathrm{pH}-\mathrm{pK}_1'}\) predicts they should. Changing pCO2 from 40 to 55 mmHg moves the ratio by 0.0025, because it scales the open and closed capacities together. Switching the water constant from 37 °C back to 25 °C changes the ratio in the fifth decimal place, which is as clear a statement as you could want that water contributes nothing at blood pH.
Two modelling choices would have changed the published number. First, apparent pK2'. We used 9.80. The thermodynamic value near 10.33 gives a ratio of 20.487 instead of 19.498, a 5% shift, because the carbonate ion enters the open capacity with a weight of four. There is no consensus figure for plasma, so we put a uniform prior across the published range and carried it through. The same sensitivity turns up in ocean carbonate work, where the equivalent buffer factors depend sharply on which constants you adopt [14]. Second, the decision to derive bicarbonate from pH and pCO2 rather than to fix it at the clinical 24 mmol/L. Fixing it would have given a slightly smaller open capacity and a story about how well the model agrees with a number we had put in by hand.
That distinction is worth being blunt about. The Monte Carlo mean of 20.1620 sits 245 standard errors from the central-value calculation of 19.4975, and for about ten minutes we treated that as a disagreement. It is not. The central value uses pK2' = 9.800, the bottom edge of the uniform prior, whose own mean is 10.100. Recomputing the central value at 10.100 gives 20.1848, which sits two percent of one standard deviation from the Monte Carlo mean. The remainder is genuine curvature, since the ratio is nonlinear in pH and the average of a function is not the function of the average.
Reproducing This, and the Thing We Keep Coming Back To
Everything above comes from one file. From the repository root:
python buffer-capacity.py > buffer-capacity-output.txt
Python 3.12.3 and NumPy 2.4.2 were used here. NumPy supplies the PCG64 generator for the Monte Carlo and nothing else; the equilibrium work is standard-library arithmetic. The master seed is 20250321, stated in the first line of the output. Expected runtime is under a second on a school laptop, and the ten-minute budget the club sets for its studies was never in danger. Running the file twice produces byte-identical output. Passing --svg <directory> writes the five figures above as SVG fragments from the same arrays that produced the tables, so no figure in this article was drawn by hand or adjusted afterwards.
And then there is the thing none of us can put down.
We started this because buffer capacity looked like a formula worth computing properly, and it was. The peak really is at pKa, to four decimal places, and the small residual turns out to be water. The window really is 1.531 pH units wide, and \(3 + 2\sqrt{2}\) really does fall out of a quadratic. Those are satisfying in the ordinary way that correct arithmetic is satisfying.
The carbon dioxide result is not like that. Blood is buffered by a weak acid whose dissociation constant is in the wrong place by a factor of twenty, at a concentration that ought to be far too low, and it works anyway, because the buffer is plumbed into a gas exchanger that runs about twelve times a minute and holds one of its two components at a constant value. The chemistry on its own is worth 2.94. The chemistry with the plumbing is worth 57.32. Every textbook diagram of the bicarbonate buffer that stops at the equilibrium arrows has drawn the less interesting half of the mechanism.
I keep thinking about the 3.85. Being 1.3 pH units away from your own optimum is supposed to be a design flaw. In an open system it is the whole point, because the distance is what fills the solution with bicarbonate. Sitting in the wrong place turns out to be the trick, provided someone is carrying the carbon dioxide away, which at this moment happens to be me.
References
- Henderson, L. J. (1908). Concerning the relationship between the strength of acids and their capacity to preserve neutrality. American Journal of Physiology 21, 173–179. doi:10.1152/ajplegacy.1908.21.2.173
- Hasselbalch, K. A. (1917). Die Berechnung der Wasserstoffzahl des Blutes aus der freien und gebundenen Kohlensäure desselben, und die Sauerstoffbindung des Blutes als Funktion der Wasserstoffzahl. Biochemische Zeitschrift 78, 112–144. No DOI was ever assigned to this article.
- Van Slyke, D. D. (1922). On the measurement of buffer values and on the relationship of buffer value to the dissociation constant of the buffer and the concentration and reaction of the buffer solution. Journal of Biological Chemistry 52, 525–570. doi:10.1016/S0021-9258(18)85845-8
- Harned, H. S. & Ehlers, R. W. (1932). The dissociation constant of acetic acid from 0 to 35 degrees centigrade. Journal of the American Chemical Society 54, 1350–1357. doi:10.1021/ja01343a013
- Ellison, G., Straumfjord, J. V. & Hummel, J. P. (1958). Buffer capacities of human blood and plasma. Clinical Chemistry 4, 452–461. doi:10.1093/clinchem/4.6.452
- Good, N. E., Winget, G. D., Winter, W., Connolly, T. N., Izawa, S. & Singh, R. M. M. (1966). Hydrogen ion buffers for biological research. Biochemistry 5, 467–477. doi:10.1021/bi00866a011
- Siggaard-Andersen, O. (1971). An acid-base chart for arterial blood with normal and pathophysiological reference areas. Scandinavian Journal of Clinical and Laboratory Investigation 27, 239–245. doi:10.3109/00365517109080214
- Roos, A. & Boron, W. F. (1981). Intracellular pH. Physiological Reviews 61, 296–434. doi:10.1152/physrev.1981.61.2.296
- Stewart, P. A. (1983). Modern quantitative acid-base chemistry. Canadian Journal of Physiology and Pharmacology 61, 1444–1461. doi:10.1139/y83-207
- de Levie, R. (1993). Explicit expressions of the general form of the titration curve in terms of concentration. Journal of Chemical Education 70, 209. doi:10.1021/ed070p209
- Urbansky, E. T. & Schock, M. R. (2000). Understanding, deriving, and computing buffer capacity. Journal of Chemical Education 77, 1640. doi:10.1021/ed077p1640
- Po, H. N. & Senozan, N. M. (2001). The Henderson-Hasselbalch equation: its history and limitations. Journal of Chemical Education 78, 1499. doi:10.1021/ed078p1499
- Boron, W. F. (2004). Regulation of intracellular pH. Advances in Physiology Education 28, 160–179. doi:10.1152/advan.00045.2004
- Egleston, E. S., Sabine, C. L. & Morel, F. M. M. (2010). Revelle revisited: buffer factors that quantify the response of ocean chemistry to changes in DIC and alkalinity. Global Biogeochemical Cycles 24, GB1002. doi:10.1029/2008GB003407
- Shaw, I. & Gregory, K. (2022). Acid-base balance: a review of normal physiology. BJA Education 22, 396–401. doi:10.1016/j.bjae.2022.06.003
- Bellelli, A. (2025). Blood buffers: the viewpoint of a biochemist. Physiological Reports 13, e70333. doi:10.14814/phy2.70333