fivenines
17/39
Lesson 2.2

The hot standby: replicated state machines

What you'll learn

How determinism turns replication from a hard problem into a subscription — and what failover looks like when the standby is already caught up.

Building on

Lesson 1.7's punchline: state = f(sequenced log). Here is where it pays out.

Replicating a mutable database is painful: which writes have propagated? Are replicas transactionally consistent? Our core sidesteps all of it. The engine is a deterministic function of the log — so a replica is just a second engine consuming the same log. No state synchronization protocol, no diffing: identical inputs in identical order produce identical state, every event, by construction.

sequenceDiagram
    autonumber
    participant S as Sequenced stream
    participant P as Primary engine
    participant B as Standby engine
    participant F as Failover controller
    S->>P: event 1041
    S->>B: event 1041
    P->>P: process, PUBLISH outputs
    B->>B: process identically, SUPPRESS outputs
    Note over P: primary dies after event 1041
    F->>F: heartbeat missing ×3 (~600 ms)
    F->>P: fence — old primary may no longer publish
    F->>B: promote
    B->>B: confirm processed through 1041
    B->>S: publishing resumes from event 1042
    
Hot-standby failover. The standby isn't restoring anything — it has been processing all along, seconds of work behind at most. Failover = stop suppressing outputs. Sub-second is achievable; single-digit seconds is comfortable.

The three rules that make this correct:

  • Exactly one publisher. Both replicas compute everything; only the primary's outputs (fills, market data) leave the building. Two publishers would double-send every fill.
  • Fence before promote. The old primary might be alive-but-slow rather than dead (the gray failure — 3.5). Before the standby publishes, the old primary must be verifiably cut off — downstream systems reject its epoch (2.6 formalizes this).
  • Resume, don't rewind. The new primary continues from the exact event where outputs stopped. Consumers see a pause, never a repeat and never a gap — the sequence numbers guarantee they can prove it.

Cost accounting, honestly: 2× core compute (a rounding error next to venue revenue), plus one sharp new risk — correlated software failure. If event 1041 is a poison message that crashes the primary via a matching bug, it crashes the standby identically one instant later, because determinism replicates bugs with the same fidelity as state. Lesson 0.3's warning made concrete. Mitigations: run standbys one software version behind during rollouts (2.5 exploits this deliberately), aggressive input validation at the sequencer, and a rehearsed break-glass path back to restart-and-replay. Determinism giveth; determinism replicateth the bug.

Key ideas
  • A replica = another subscriber to the log. Determinism does the synchronization.
  • One publisher; fence the old before promoting the new; resume exactly.
  • Determinism replicates bugs too — version-stagger your replicas.
Next step

See what actually stuck.

Take the practice scenarios now.