If you ask any software engineer what their weekend hobby is, there is a surprisingly high probability the answer is sourdough bread baking.
Both disciplines scratch the same neurological itch: deterministic algorithms meeting complex organic state machines. You feed living wild yeast cultures, balance flour-to-water ratios, and wait for bulk fermentation state transitions.
Yet, after baking hundreds of loaves and analyzing popular bread calculators across the web, I discovered a glaring mathematical flaw that plagues almost every conventional baking calculator: the hidden 3% hydration trap.
Here is why standard calculators fail, the polymer science behind dough stickiness, and how we engineered an open-source, edge-rendered solution using Next.js 14, Cloudflare, and thermodynamic physics.
1. The Hidden 3% Hydration Flaw
In standard baker's percentage accounting, every ingredient is calculated relative to the total flour weight ($100\%$).
A classic recipe might read:
- Flour: $500\text{g}$ ($100\%$)
- Water: $375\text{g}$ ($75\%$)
- Levain (Starter): $100\text{g}$ ($20\%$)
- Salt: $10\text{g}$ ($2\%$)
The baker assumes they are handling a $75\%$ hydration dough.
The Mathematical Bug:
A standard sourdough starter is maintained at $100\%$ hydration (equal parts flour and water by weight). That means your $100\text{g}$ of levain is secretly:
- $50\text{g}$ flour
- $50\text{g}$ water
When you recalculate the True Total Hydration across the entire dough matrix:
$$\text{Total Flour} = 500\text{g} + 50\text{g} = 550\text{g}$$
$$\text{Total Water} = 375\text{g} + 50\text{g} = 425\text{g}$$
$$\text{True Total Hydration} = \frac{425\text{g}}{550\text{g}} \times 100\% = \mathbf{77.27\%}$$
That is a $+2.27\%$ unexpected surge in liquid water! If the baker uses a higher inoculation (e.g. $25\%$ starter), the error spikes beyond $+3.2\%$.
To a baker aiming for a manageable $75\%$ loaf, an unexpected $78\%$ matrix means the gluten network loses its elastic modulus ($G'$), resulting in an uncontrollable, sticky puddle on the bench.
2. Modeling Multi-Flour Water Absorption Limits
Different flours possess radically different water absorptions due to damaged starch, protein content, and pentosan polymers:
- Unbleached Bread Flour: baseline $72\%\text{ - }76\%$
- Stoneground Whole Wheat: bran fibers absorb water rapidly ($80\%\text{ - }85\%$)
- Rye Flour: rich in mucilaginous arabinoxylans, absorbing up to $85\%\text{ - }90\%$ water but forming zero traditional gluten networks.
We modeled this in TypeScript as a weighted absorption rheology engine:
export interface FlourComponent {
id: string;
name: string;
weightGrams: number;
proteinPercent: number;
absorptionRatio: number; // e.g. 0.74 for bread flour, 0.85 for rye
}
export function calculateEffectiveAbsorptionCapacity(flours: FlourComponent[]): number {
const totalWeight = flours.reduce((acc, f) => acc + f.weightGrams, 0);
if (totalWeight === 0) return 0.75;
const weightedSum = flours.reduce(
(acc, f) => acc + f.weightGrams * f.absorptionRatio,
0
);
return weightedSum / totalWeight;
}
3. The Summer DDT Crisis: When Water Must Be Colder Than Ice
Professional bakers rely on Desired Dough Temperature (DDT) to control fermentation kinetics:
$$T_{\text{water}} = (3 \times \text{DDT}) - (T_{\text{room}} + T_{\text{flour}} + T_{\text{starter}} + \text{Friction Factor})$$
The Physical Impossibility in Hot Climates:
Suppose your summer kitchen is at $86^\circ\text{F}$ ($30^\circ\text{C}$), flour is $84^\circ\text{F}$, starter is $82^\circ\text{F}$, and mixer friction is $4^\circ\text{F}$. You target a standard DDT of $76^\circ\text{F}$.
Plug this into the formula:
$$T_{\text{water}} = (3 \times 76) - (86 + 84 + 82 + 4) = 228 - 256 = \mathbf{-28^\circ\text{F}}\;(-33.3^\circ\text{C})$$
Liquid water cannot exist at $-28^\circ\text{F}$.
Standard calculators either crash, throw an error, or tell the baker "chill your water," which is physically inadequate because liquid water cannot drop below $32^\circ\text{F}$ ($0^\circ\text{C}$).
The Thermodynamic Fix: Latent Heat of Fusion
Ice does not merely cool water by its temperature difference—it absorbs $80\text{ cal/g}$ ($334\text{ J/g}$) of energy purely to break hydrogen bonds during phase change (latent heat of fusion).
We implemented the thermodynamic energy balance equation:
$$m_{\text{ice}} = m_{\text{water, total}} \times \frac{T_{\text{tap}} - T_{\text{target}}}{T_{\text{tap}} + 144 - T_{\text{ice}} \times 0.5}$$
(where 144 is the BTU/lb latent heat constant)
With this equation, the engine computes the exact gram-for-gram replacement:
- Crushed Ice: $142\text{g}$
- Chilled Tap Water: $233\text{g}$
When the ice melts during autolyse, the resulting bulk dough hits $76^\circ\text{F}$ within $\pm 0.5^\circ\text{F}$.
4. Open-Sourcing the Rheology Engine
We extracted the core mathematics and thermodynamic physics into a zero-dependency open-source library:
-
GitHub Repository:
forestelf/sourdough-physics - Live Web App: SourdoughCalc.app
- License: MIT
The frontend is built on Next.js 14 App Router, deployed globally to Cloudflare Pages edge locations with $<50\text{ms}$ Time to First Byte (TTFB). It also includes a kitchen companion mode with the Screen Wake Lock API, keeping your phone display alive while kneading flour-covered dough.
5. What's Next?
We recently added kinetic microbial timing for starter feeding ratios ($1:1:1$, $1:2:2$, $1:5:5$) and geometric bulk rise calibration for conical mixing bowls.
Are you baking sourdough or working on computational food science? Check out the live tool or explore the code on GitHub. Feedback and edge-case pull requests are warmly welcomed!
Top comments (0)