Skip to content

Gravity, IBU and colour

Specific gravity to degrees Plato is the ASBC cubic fit of the Plato table:

°P = -616.868 + 1111.14·SG − 630.272·SG² + 135.997·SG³

Accurate to well under 0.1 °P from 1.000 to 1.130. Going the other way, the standard inversion used by brewing calculators:

SG = 1 + °P / (258.6 − (°P / 258.2) × 227.1)

These two are different published approximations, so they are not exact inverses of each other — a round trip loses about 0.05 °P. Attenuation is defined on extract, so anywhere the engine has to predict a final gravity and then read the attenuation back off it, it inverts the same cubic numerically (Newton–Raphson, converging to about 10⁻¹² SG) rather than using the second formula. A visible consequence: the cubic reads −0.003 °P at SG 1.000, so it does not pass exactly through the origin.

Brix is treated as Plato. The two scales differ (sucrose versus maltose reference) but are within about 0.05 of each other over the brewing range; the wort correction factor a refractometer needs is a separate concern.

The engine’s internal currency for extract is point·litres:

pointLitres = kg × pointsPerKgPerL × efficiency
SG = 1 + (Σ pointLitres) / volumeL / 1000

A fermentable’s yield, in points per pound per US gallon, as weighed out:

PPG = ((FGDB% − fine/coarse difference%) / 100) × (1 − moisture% / 100) × 46.214

The moisture term converts a dry-basis laboratory figure to the as-is grain you actually weigh. 46.214 is the yield of pure sucrose — one pound dissolved to one US gallon gives 1.04621 SG — from Palmer, How to Brew, 4th edition. The conversion between the two yield units is exact: points·L/kg = PPG × 8.345404.

If a fermentable carries an explicit PPG, that wins. If it carries neither a PPG nor an extract percentage, the calculation refuses rather than guessing. Moisture defaults by class: 4 % for grain and steeping grain, 2 % for dry extract, 20 % for liquid extract, zero for sugars.

Efficiency depends on how the addition is used, not only on what it is. Extract and sugar always convert fully. Grain converts at mash efficiency when mashed, at the steeping efficiency (50 % by default) when steeped or boiled, and at zero in the whirlpool or the fermenter — grain thrown at a whirlpool contributes no extract at all.

Mash efficiency is what you set on the equipment profile and what the grist is scaled by. Measured from a pre-boil sample:

mashEff% = 100 × (measuredPoints × volume − Σ fixed-efficiency point·litres)
/ Σ mashable theoretical point·litres

For an all-extract recipe there is nothing mash efficiency applies to, so the engine returns “no answer” rather than 0 % — reporting zero would be a lie rather than an absence, and the app shows a dash.

Brewhouse efficiency is the whole-process figure, measured against the wort that actually reached the fermenter:

brewhouseEff% = 100 × (OG points × fermenter volume) / Σ theoretical point·litres

Extract is accumulated in three stages — pre-boil (mash and steep), boil (boil and whirlpool), and fermenter — and divided by the volume at that stage.

Original gravity equals the post-boil gravity: losses between the kettle and the fermenter remove wort, not concentration. Sugars added in the fermenter are not in the OG you measure, so the engine also reports an OG equivalent that includes them, and it is the OG equivalent that ABV is calculated from. A recipe with fermenter sugar will therefore report a higher ABV than the hydrometer numbers alone would give — correctly.

Final gravity comes from a weighted attenuation:

netADF = Σ (extract_i × attenuation_i) / Σ extract_i
AE = OE × (1 − netADF)
FG = SG(AE)

An addition’s attenuation is its own fermentability if it has one; sugar is 100 %, a non-fermentable is 0 %, and everything else takes the yeast’s figure — the midpoint of the strain’s published range, or the maximum across a blend, since with several strains pitched together the most attenuative one dominates the finished beer. With no yeast at all the engine assumes 75 %, the middle of the range for a typical American ale strain.

An optional mash-temperature adjustment shifts attenuation by 1.2 points per °C away from 66.7 °C, clamped to ±8 points. It is off by default and the engine’s own comment is explicit that it is a heuristic, not a published formula: it reproduces the “mash at 149 °F for a dry beer, 156 °F for a full one” rule of thumb and nothing more.

Two formulas. The rule of thumb everyone quotes:

ABV% = (OG − FG) × 131.25

A linear fit, close enough below about 1.070 and increasingly optimistic above it. Kept because it is what recipe books print and you should be able to reproduce it.

The default, per PLAN §5.1:

ABV% = (76.08 × (OG − FG) / (1.775 − OG)) × (FG / 0.794)

The first term is alcohol by weight from the gravity drop; FG / 0.794 converts weight to volume using the density of ethanol. Widely attributed to a 1995 Zymurgy article (the engine’s formula key names Cutaia) and used by BeerSmith, Brewer’s Friend and Brewfather alike. It diverges from the rule of thumb above about 7 % ABV, where it is the trustworthier of the two: for 1.090 → 1.020 the two give 9.19 % and 9.99 %.

  • Apparent attenuationADF = 100 × (OE − AE) / OE. The definition every yeast lab quotes attenuation against.
  • Real extractRE = 0.1808 × OE + 0.8192 × AE, Balling’s relation.
  • Real attenuation100 × (OE − RE) / OE, which with Balling’s relation collapses exactly to 0.8192 × ADF: the familiar “real is about 80 % of apparent” rule, derived rather than asserted. ASBC’s laboratory figure carries a further correction for the CO₂ that left the beer; that is a few tenths of a percent and is not modelled.
  • Alcohol by weightABW = (OE − RE) / (2.0665 − 0.010665 × OE), the standard relation used with Balling’s real extract.
  • Calorieskcal/12 oz = [6.9 × ABW + 4.0 × (RE − 0.1)] × FG × 3.55, the standard brewing-industry formula: 6.9 kcal/g for ethanol, 4.0 kcal/g for carbohydrate, scaled by the mass of a 12 oz serving. Per litre and per 330 mL are derived from it.

All three models compute the same product:

IBU = utilisation × (mg/L of alpha acid)
mg/L = alphaAcid% / 100 × mass_g × 1000 / volume_L

and differ only in the utilisation term.

Source: Glenn Tinseth, “Hop Utilization” (1997), realbeer.com. Two factors, multiplied:

bigness factor = 1.65 × 0.000125^(Gb − 1)
boil time factor = (1 − e^(−0.04t)) / 4.15

The bigness factor models the suppression of iso-alpha-acid solubility by wort gravity, where Gb is the boil gravity. The boil-time factor is the integrated form of a first-order isomerisation with rate 0.04 min⁻¹, normalised so utilisation asymptotes at 1/4.15 ≈ 0.241. This reproduces Tinseth’s published utilisation table exactly, because that table is generated from this formula: 1.050 at 60 minutes gives 0.231.

Beerwright feeds it post-boil gravity by default. Tinseth’s own guidance is to use the average gravity over the boil; most calculators use post-boil, and matching them is the deliberate choice so that a recipe’s numbers line up with BeerSmith and Brewfather.

Source: Jackie Rager, Zymurgy Special Issue 1990.

U(t) = (18.11 + 13.86 × tanh((t − 31.32) / 18.27)) / 100

with a gravity adjustment (Gb − 1.050) / 0.2 above 1.050, applied as a divisor (1 + GA) on the final IBU. Systematically higher than Tinseth; Rager’s own note is that his numbers suit full-wort boils.

Source: Mark Garetz, Using Hops (1994).

U(t) = (7.2994 + 15.0746 × tanh((t − 21.86) / 24.71)) / 100

divided by three multiplicative penalties: a gravity factor, a hopping-rate factor IBU_total / 260 + 1, and a temperature factor 1 + (elevation_ft / 550) × 0.02 — elevation lowers the boiling point and with it isomerisation. The hopping-rate factor depends on the answer, so Garetz is solved by fixed-point iteration. The concentration factor Garetz also defines is 1 here, because the alpha acids are already expressed against the same volume.

A stand below boiling still isomerises, and modern hoppy recipes are unusable without accounting for it. Beerwright converts a stand into effective boil minutes using the Arrhenius rate from Malowicki, Hop bitter acid isomerization and degradation kinetics (MSc, Oregon State, 2005):

k₁(T) = 7.9×10¹¹ × exp(−11858 / T) T in kelvin

At 100 °C that is 0.01245 min⁻¹ — deliberately not Tinseth’s 0.04 min⁻¹. Tinseth’s constant is an empirical fit to measured utilisation and lumps in losses to trub, break and foam. The two are only ever used together as a ratio to boiling, in which the absolute rate cancels and only the well-established temperature dependence survives. That ratio is 0.165 at 80 °C and 0.022 at 60 °C.

Two stand models:

  • mIBU (the default shape) integrates the ratio over an exponential cooling curve, T(τ) = T_ambient + (T₀ − T_ambient) · e^(−kτ), following John-Paul Hosom, A Modified IBU Calculation (2018). The cooling constant defaults to 0.015 min⁻¹ — a stand starting at 80 °C is still at 64 °C twenty minutes later, which is what a covered 20 L kettle actually does. Turn it up to 0.05–0.10 if you run an immersion chiller through the stand. A 20-minute stand at 80 °C is worth 1.64 effective boil minutes.
  • Fixed temperature multiplies the stand length by the ratio at one temperature. Right for a recirculating whirlpool with active temperature control; optimistic for a kettle left to cool. It is the k → 0 limit of the other model.
  • Boil — the stated time at boiling.
  • First wort — the full boil time, times 1.10. FWH sits in the kettle while it heats and isomerises throughout; the 1.10 is the BeerSmith and Brewer’s Friend convention, itself from the 1995 Brauwelt trials that measured about 10 % more bitterness than an equivalent 60-minute addition.
  • Whirlpool — the stand, converted as above.
  • Dry hop — exactly 0 IBU. Dry hops add aroma and, perceptually, bitterness, but no measurable iso-alpha-acid.

Hop form multiplies utilisation: whole and plug 1.0 (the baseline every published table was measured against), pellet 1.10 for the increased surface area of milled cones. Cryo also gets 1.10, not more: its extra bitterness is already carried by its roughly doubled stated alpha-acid percentage, and a second potency multiplier would count it twice.

BU:GU = IBU / ((OG − 1) × 1000)

Around 0.5 is balanced, 0.8 or above is firmly bitter, 0.3 or below is malty.

Malt colour units first, in the US customary units every published SRM fit was regressed against:

MCU = Σ (weight_lb × colour_°L) / volume_gal

Colour is set in the kettle, so the volume is normally the post-boil volume. Then one of three fits from MCU to SRM.

Morey (1999) — the default:

SRM = 1.4922 × MCU^0.6859

Fitted by Dan Morey to the Daniels and Mosher data plus Noonan’s tables. The best-behaved of the three across the whole range, which is why essentially every modern calculator defaults to it.

Daniels — Ray Daniels, Designing Great Beers (1996):

SRM = 0.2 × MCU + 8.4

A straight line regressed over roughly MCU 7–50. It cannot return less than 8.4 SRM, so it is visibly wrong for pale beers.

Mosher — Randy Mosher, The Brewer’s Companion (1994):

SRM = 0.3 × MCU + 4.7

Regressed on commercial beers, so it too has a floor, at 4.7 SRM.

Beerwright departs from the last two deliberately: below the crossover (MCU 10 for Daniels, MCU 7 for Mosher) it clamps to Morey rather than report a pale lager as amber. If you pick Daniels and get a paler answer than the straight line gives, that is why.

Conversions: EBC = SRM × 1.97, and SRM = 1.3546 × °L − 0.76 (Daniels) is available as a helper — though the colour pipeline consumes a malt’s Lovibond figure directly and never applies it.

The swatch shown next to a recipe interpolates the standard 40-step beer-colour chart in sRGB. It is a swatch, not a colorimetric transform, and is documented as approximate.