Nitrogen cycle
What it models
Section titled “What it models”Organic matter rots to ammonia, ammonia becomes nitrite, nitrite becomes nitrate. Two bacterial guilds run the last two stages, and both pay in dissolved oxygen — 4.57 mg of O₂ per mg of nitrogen carried the whole way, three quarters of it on the first step. The colonies grow on the work they actually do and fade on a maintenance clock that never stops, so a biofilter is a stock the tank has to keep earning.
Status
Section titled “Status”| Mechanic | Status | Why |
|---|---|---|
| Three-stage chain | settled | Compound mass converts through the molecular weights in src/; no tunable restates one. |
| Ammonia source | settled | Every organic pool rots — food and waste in the water, the bed’s mulm where it lies — releasing what its composition holds. |
| Processing capacity | settled | Population × per-cell throughput × warmth × air, with no volume term — the same colony clears the same mass in a nano and a 300 L. |
| Substrate limitation | settled | Monod on total ammonia for AOB and on nitrite for NOB, so a cycled tank holds hundredths of a ppm and a pulse stands until the colony works it down. |
| Colony growth and decay | settled | Logistic growth scaled by utilization; unconditional maintenance decay on a 21-day half-life. |
| Oxygen limitation | settled | Monod on both guilds, NOB’s half-saturation nearly 4× AOB’s — which is where standing nitrite comes from. |
| Temperature | settled | One Q10 factor across oxidation, growth and decay, because they are one metabolism. |
| Guild seeding | settled | A trickle per litre of water that never stops, so a guild is always present and grows the moment it has feedstock — no concentration gate. |
| Rot | settled | One first-order law for every pool, each at its own rate: Q10 on temperature, a Monod on the oxygen there is, and a slow anaerobic path that runs without it. |
| Ammonia’s other consumers | settled | Plants and the blooms take ammonia into their stores, from what the colony left; the colony works on what they leave and the hour’s arrivals. |
| N mass conservation | settled | Water, organics, the bed’s store and every body — plant and bloom tissue and stores, fish, their guts and their clutches — conserve N per atom, whichever form it was taken in. It enters only as food, fertilizer, root tabs and stocked fish and plants, and leaves only with water changes, the gravel vac and the fish and plants taken out. |
| Colony sizing on inert beds | settled | A colony grows to the load it is fed, not to the surface under it, so an inert bed’s smaller surface lowers the ceiling without setting the cycling clock. |
| Cycled seed | settled | A 'cycled' colony is the one the tank’s load sustains at rest — its fish eating the ration that pays their upkeep, and its bed’s mulm rotting — floored at a fishless month’s share of the surface ceiling. A seeded colony already clears its resting load at the trace line, so a stocked setup opens without a spike; food fed past upkeep is outside that load, so an overfed tank’s colony grows on from the seed. |
| Nitrogen alerts | settled | Free NH₃, nitrite and nitrate alert at the shared *_s, the lines every fish’s own edge is read off. |
| Bed disturbance | scaffolding | Lifting hardscape stirs one slot’s share of the bed per piece, and uprooting a plant its own patch: that share of the mulm comes loose as waste and its biofilm is scraped off. The bed holds days to weeks of the tank’s waste, so a rescape shows as a bump the colony works down. |
| Denitrification | missing | Nitrate has no biological sink. It leaves only through plant growth and water changes, so an unplanted tank accumulates it without bound. |
| Nitrification acidity | settled | Stoichiometric: the 2 H⁺ each NH₄⁺ releases spend two equivalents of KH, 7.14 mg CaCO₃ per mg of nitrogen, against the one ammonia took up as it was minted — the account is on Water & gases. A tank that nitrifies without water changes loses its buffer and its pH. |
How it works
Section titled “How it works”The three stages
Section titled “The three stages”| Stage | Reaction | Run by |
|---|---|---|
| 1 · Rot | food, waste, mulm (g) → NH₃ + PO₄ + K + Fe (mg) + CO₂ | Decomposers, first order on each pool at what it holds — see where the ammonia comes from |
| 2 · Ammonia oxidation | NH₄⁺ + 1.5 O₂ → NO₂⁻ + 2 H⁺ + H₂O | AOB, saturating on what is dissolved |
| 3 · Nitrite oxidation | NO₂⁻ + 0.5 O₂ → NO₃⁻ | NOB, saturating on what is dissolved |
Nitrogen is conserved atom for atom across the chain. Compound mass is not — it
grows with molecular weight, and every conversion reads its ratio from the
shared chemistry in src/simulation/core/ so the whole engine agrees on the
arithmetic.
| Conversion | Factor | Derivation |
|---|---|---|
| NH₃ → NO₂⁻ | 2.702 | MW_ |
| NO₂⁻ → NO₃⁻ | 1.348 | MW_ |
| O₂ spent per mg NH₃ | 2.819 | 1.5 × MW_ |
| O₂ spent per mg NO₂⁻ | 0.348 | 0.5 × MW_ |
| KH per mg NH₃ minted, as CaCO₃ | +2.939 | +1 × CACO3_ |
| KH per mg NH₃ oxidised, as CaCO₃ | −5.877 | −2 × CACO3_ |
The oxygen draw is derived from the nitrogen actually oxidised, never quoted separately. A tank that cannot run the reaction does not pay for it.
Stocks and rates
Section titled “Stocks and rates”| Stock | Fills it | Drains it | Unit |
|---|---|---|---|
food | Feeding, at the food’s composition | Fish eating; rot; settling into the bed | g |
waste | Fish feces, dead fish and eggs, plant and bloom shedding and die-back, scrubbed film, a disturbed bed | Rot; settling into the bed | g |
| mulm | Food and waste settling; a fresh bed’s own organics | Rot; a gravel vac; disturbance, back into waste | g |
ammonia | Rot; fish gill excretion — a meal’s excess and every gram burned | Plant and bloom growth, from what the colony left; AOB oxidation; water change removes proportional mass | mg |
phosphate · potassium · iron | Rot, at what each pool holds; fish excretion; fertilizer dosing; the bed’s leak | Plant and bloom growth; water change | mg |
nitrite | AOB oxidation, × 2.702 | NOB oxidation; water change | mg |
nitrate | NOB oxidation, × 1.348; fertilizer dosing; the bed’s leak | Plant and bloom growth, for the nitrogen ammonia leaves; water change | mg |
aob | Seeding trickle; logistic growth on utilization | Maintenance decay; surface-area cap | units of 10⁶ cells |
nob | Seeding trickle; logistic growth on utilization | Maintenance decay; surface-area cap | units of 10⁶ cells |
oxygen | Gas exchange, elsewhere | Aerobic rot, 32/12 of the carbon it oxidises; 2.819 mg per mg NH₃ and 0.348 mg per mg NO₂⁻ oxidised | mg/L |
A water change dilutes the three nitrogen compounds but leaves the food and waste standing in the water; only a gravel vac takes organic matter out, and only the mulm in the bed.
Storage is mass, not concentration
Section titled “Storage is mass, not concentration”Nitrogen compounds are stored as mass in mg, and a concentration is derived from that mass and the standing water only where a threshold or a display needs one. Storing the conserved quantity is what makes evaporation concentrate the tank for free: same mass, less water, higher ppm, no code. Oxygen is the exception — it is stored as a concentration, so both oxidation steps divide their oxygen bill by standing water before pushing the effect.
On a drained tank that derivation returns 0, and both oxidation stages are gated
on water > 0: nitrifiers oxidise what is dissolved. Maintenance decay sits
outside that gate on purpose, so a colony in a drained tank dies back rather
than waiting.
Processing capacity
Section titled “Processing capacity”capacity = population × processingRate × warmth × airconsumed = capacity × S / (K + S) // S: concentration the tick ends onutilization = consumed / capacity // 0..1, dimensionlessEach guild saturates on its own substrate as well as on oxygen: AOB on total ammonia, NOB on nitrite. Capacity is the maximum a colony reaches in a glut; in ordinary water it runs at a Monod share of it, so a colony works in proportion to what is dissolved rather than at a fixed pace up to its limit.
The curve is read at the concentration the tick ends on — the root of
consumed = capacity × monod(standing − consumed). Read at the start instead, a
colony with more throughput per hour than the half-saturation mass would empty
the pool every tick and a cycled tank would read exactly zero. Read at the end,
uptake never exceeds either the stock or the capacity, and a steady state rests
where the continuous curve puts it.
| Guild | Substrate | Half-saturation K | Source |
|---|---|---|---|
| AOB | NH₃ + NH₄⁺, as NH₃ | 0.61 ppm (0.5 mg/L N) | Nitrosomonas, low end of wastewater models’ 0.5–1 mg/L N |
| NOB | NO₂⁻ | 0.66 ppm (0.2 mg/L N) | Nitrospira, the guild that dominates aquarium biofilters, 0.1–0.3 mg/L N |
Capacity carries no volume term. Throughput is a property of the cell, so the same colony clears the same milligrams in a nano and in a 150 L — which is what makes a ppm reading fall with volume the way it does in a real tank.
NOB take the same per-cell throughput scaled by ≈ 2.951. That is the 2.702 mass ratio
re-quoted through each guild’s own oxygen factor at air saturation, rather than
the bare ratio, which would hand NOB AOB’s correction on top of their own and
leave them 8.4 % under parity.
Colony dynamics
Section titled “Colony dynamics”| Flow | Form | Gated on |
|---|---|---|
| Seeding | water × seeding, both guilds | Standing water; held under the surface ceiling |
| Growth | pop × growth | Utilization — nothing to oxidise means no growth |
| Decay | pop × death | Nothing. It is unconditional |
| Surface cap | Population truncated to surface × bacteria | Surface leaving the tank — a rescape, a media change |
| Disturbance | The disturbed share of the bed’s colony scraped off; a lifted piece takes its own biofilm | A keeper digging into the bed |
Seeding is how a colony starts: cells settle out of the fill water and the air
every tick, so a guild is never absent and emerges on exponential growth the
moment its feedstock appears. With nothing to eat, a guild idles at
seedingRate / deathRate — about 73 cells/mL. The rate is the cycling clock,
and logarithmic in it: each tenfold cut adds three to four days.
air scales oxidation and growth alike, because a colony cannot divide on a
reaction it cannot run. It deliberately does not scale maintenance decay, which
is what makes an anoxic tank lose its biofilter rather than merely pause it.
Decay is maintenance loss, not starvation. Bacteria fade over weeks rather than collapsing when the meal ends, which is why a tank survives a holiday.
A colony under a steady load settles where the two flows cancel:
utilization_rest = deathRate / (growthRate × air × (1 − pop/max))In air-saturated water with the ceiling far off, that is 4.0 % for AOB and
7.1 % for NOB. The rest point moves with oxygen, and not with temperature —
warmth cancels out of it, because a cell that oxidises half as fast also
divides and starves half as fast.
Utilization is the substrate curve, so the rest point fixes the concentration a
cycled tank holds: S = K × u / (1 − u) — about 0.03 ppm ammonia and 0.05 ppm
nitrite, almost whatever the load. A heavier load grows a bigger colony, not a higher
reading. A pulse lifts S and with it the colony’s pace, so it clears in hours
on a mature colony with headroom and in days on one still growing into its load.
Oxygen: why nitrite stands
Section titled “Oxygen: why nitrite stands”| Guild | Half-saturation K | Rate left at 8.38 mg/L | Rate left at 0.10 mg/L |
|---|---|---|---|
| AOB | 0.30 mg/L | 96.5 % | 25.0 % |
| NOB | 1.10 mg/L | 88.4 % | 8.3 % |
Every base rate multiplied by that factor is a Monod maximum, reached only at infinite oxygen. The three nitrifier rates divide the shortfall back out, so what a tank at air saturation reproduces is the quoted 20 h doubling rather than the 20.7 h an uncorrected constant would give.
Both guilds read their oxygen where the hour leaves it, once rot, both
oxidations and the air have drawn on the one stock together
(Water & gases).
The ratio between the two guilds runs from 1.000 at air saturation to 0.364
at 0.10 mg/L. That gap is the whole story of standing nitrite: a tank short of
air goes on oxidising its ammonia long after it has stopped clearing the nitrite
that ammonia becomes.
Oxygen, not surface, is the binding constraint on a mature colony. Held under a saturating dose, a bare 200 L settles at 95 % of its surface ceiling for AOB and 53 % for NOB — against 96 % / 94 % with the oxygen term switched off. Circulation decides how far short a guild stops: NOB run from 1.4 % with nothing moving the water to 90.1 % on a canister, an air pump and a powerhead.
Who else takes the ammonia
Section titled “Who else takes the ammonia”Plants and the blooms take their nitrogen as ammonia first (Plants), and they run in the living tier, before the cycle: each hour they draw on what the colony left, and the colony meets what they leave beside the hour’s gill excretion; what rots lands beside the colony’s work and meets it the next hour. Each side draws through its own end-of-tick Monod, so neither overdraws the stock.
Flora take ammonia only as their stores lack it, so beside a stocked tank’s load they are a small drain — about 1 % in a community tank with a few easy plants, 5–15 % in a planted one — and a colony that still gets the rest settles at its usual trace. Where they take most of it, the colony shrinks to what is left and ammonia falls under that trace, to where the flora’s draw meets the supply. An uncycled tank’s rising ammonia feeds them fully.
Temperature
Section titled “Temperature”warmth = q10 ^ ((temperature − referenceTemp) / 10)One metabolism, one factor: oxidation, growth and maintenance all carry it. A cold tank therefore needs a larger colony to clear the same load and takes longer to build it — an 18 °C cycle runs about twice the days a 25 °C one does — while the utilization the colony rests at does not move.
Where the ammonia comes from
Section titled “Where the ammonia comes from”Rot and the fish. Every organic pool rots on one law: first order on what it
holds, Q10 on temperature, aerobic on a Monod of the oxygen there is, and a
slow anaerobic path, anaerobicShare of the pace, taking over as the oxygen
runs out. What rots releases what the pool is made of — its nitrogen as
ammonia, its phosphorus, potassium and iron to the water, its carbon as CO₂.
Food and waste also settle into the bed as mulm, fastest in still water and
halving at settlingHalfTurnover tank turnovers an hour; a bare bottom holds
none. Every pool moves its content with its grams, so the nitrogen in the bed
is the nitrogen that left the water.
| Pool | Where | Half-life, 25 °C, oxygenated |
|---|---|---|
food | The water | ~14 h |
waste | The water | ~1.5 d |
| mulm | The bed | ~10 d |
A fish excretes the rest at its gills: a meal’s nitrogen past what its reserve builds, and every gram of reserve it burns (Livestock) — so a richer food makes more ammonia.
A fresh bed’s mulm rots down until what settles in balances what rots. A water change can vacuum the bed, taking a share of its mulm out of the tank.
| Substrate | Colony surface | Organic reserve |
|---|---|---|
none | 0 cm²/L | 0 g/L |
sand | 400 cm²/L | 0.011 g/L |
gravel | 800 cm²/L | 0.013 g/L |
aqua_ | 1200 cm²/L | 0.05 g/L |
Surface and reserve are separate properties of the same bed: surface is the colony ceiling, the reserve is mulm, rotting.
Digging into the bed stirs a share of it: that share of the mulm comes loose as waste, and that share of the bed’s biofilm is scraped off.
| Move | Share of the bed disturbed |
|---|---|
| Uprooting a rooted plant | its footprint’s share of the floor — footprint / floor; an epiphyte disturbs nothing |
| Lifting a piece of hardscape | one hardscape slot — 1 / slots; the piece’s own biofilm leaves with it |
| Setting a piece down | nothing; it arrives sterile |
| Swapping the bed | all of it — the colony on it goes out with it and the new bed brings a fresh reserve |
A release lifts the concentration the colony works against, so it stands as a
bump until worked down. An established bed holds days to weeks of the tank’s
waste as mulm, so rescaping a cycled tank shows as a bump, and digging up most
of the bed at once as a larger one. An inert bed holds less mulm than soil
does, so its colony grows to a smaller load, but it cycles on the same seeding
clock. A 'cycled' seed skips the clock: each guild opens at the population
where growth on its resting load meets decay, never below a fishless month’s
share of the ceiling. That load counts the ration that pays the fish’s upkeep,
not food fed past it, so a tank whose keeper feeds more grows its colony on
from the seed.
Key tunables
Section titled “Key tunables”The tunables are listed in the reference under Nitrogen cycle, and rot and settling under Decomposition.
| Constant | Meaning | Value |
|---|---|---|
AIR_ | The water every nitrifier rate is quoted in | 8.38 mg/L |
| Neighbour | Read | Written |
|---|---|---|
| Water & gases | oxygen, where the hour leaves it — rot’s aerobic share and both guilds’ oxidation and growth | oxygen — rot’s draw and both oxidation steps’; co2, the carbon rot oxidises; kh, returned as rot mints ammonia and spent by ammonia oxidation |
| Environment | water for ppm and the submerged gate, temperature for the Q10 factor | — |
| Equipment | surface — the colony ceiling, from filter media, substrate, hardscape and glass; the bed’s mulm, rotting where it lies | Food and waste settle into the bed as mulm |
| Livestock | — | Fish eat food, write ammonia and the minerals through gill excretion, and waste as feces, dead bodies and dead eggs |
| Plants | — | Plants draw ammonia first and nitrate for the rest, with phosphate, potassium and iron, into their stores — the ammonia from what the colony left — and hand tissue back as waste when it is shed or dies, a dead plant’s stores with it |
| Algae | — | Each bloom draws the same forms from the water as plants do, ammonia first, and its shed, dead and scrubbed tissue comes back as waste, a die-back’s and a scrub’s stores with it; green water a water change takes leaves the tank |
| Actions | — | Feeding adds food; a water change removes ammonia, nitrite and nitrate mass proportionally, and a gravel vac a share of the bed’s mulm; dosing adds nitrate; uprooting a plant disturbs the bed |
| Alerts & logging | — | Free NH₃ > 0.02 ppm, nitrite > 0.5 ppm and nitrate > 80 ppm each raise an alert once per crossing |
Source
Section titled “Source”src/simulation/systems/ — with tunables in config/, molecular weights and
rate shapes in core/, the mass ↔ ppm conversion in resources/, the bed in
equipment/, and the cross-system accounting in tests/.