Raft Simulator
A Raft simulator that lets you switch off each safety rule and watch the guarantee it protects break

- random runs with every safety property holding
- 10,000
- rules you can switch off
- 7
- safety properties checked after every event
- 5
- hand-built teaching scenarios
- 12
On this page
The problem
Engineers learning distributed systems meet Raft early. It is the agreement algorithm behind etcd, Consul and CockroachDB. It keeps a group of servers agreeing on one shared record when machines crash or the network splits. It was designed to be teachable, yet the teaching tools stop in the same place.
The standard visualiser, RaftScope, was written by the paper's own author. It shows elections, messages and growing logs well. It doesn't show why each rule exists. Two gaps follow. Nothing checks Raft's five safety guarantees as a run unfolds. And nothing lets you switch a rule off to see what breaks. The paper's Figure 8 makes exactly that argument, as a static diagram most readers don't fully absorb.
I built Raft Simulator for engineers learning distributed systems, students working through the paper, and interviewers or teachers who need a live example.
What I built
The whole simulation is repeatable
The same settings, seed and user actions always produce the exact same run, on any machine. I use a virtual clock, so a thousand simulated seconds pass in microseconds. Each server is a self-contained state machine, and every number is a whole number. That one decision gives rewinding, shareable links, reproducible bug reports and large-scale random testing.
I built the rules from the paper and checked them separately
I implemented the server logic rule by rule from Figure 2 of the paper, with each rule citing the part it implements. A teaching tool that is slightly wrong teaches wrong Raft with good animations. The safety checker shares no code with the algorithm. It evaluates the five guarantees from their published definitions after every event, so it can't approve the algorithm's own bugs.
Each rule can be switched off, and the switch is enforced
Seven rules can be turned off. Each one is checked in exactly one place in the code, so no hidden second copy keeps enforcing it. Each has tests proving the guarantee breaks with it off and holds with it on. Once a rule is off, the run is marked "modified Raft" on screen and in any shared link, so nobody mistakes a broken run for the real algorithm.
Launch waited for three correctness checks
I didn't publish until three independent checks were green: the separate safety checker, random testing against the five guarantees, and one test case per Figure 2 rule. I also built two features the plan had left out of the first version: log compaction and changing cluster membership. Both changed the data model. Cluster size became a variable, so every majority check now works on configurations.
Twelve scenarios explain one thing each
Random runs are either dull or impossible to follow. So I wrote 12 scenarios by hand, each showing one named effect, such as a split vote, a stranded leader after a partition, or Figure 8 itself. Every scenario is covered by a determinism test.
Result
Raft Simulator is live and public, installable and fully offline. The main view is a log ledger. Every server's log sits in a column aligned by position, so divergence reads as a broken line and repair reads as the leader overwriting it. When a guarantee breaks, the app names the property, the position, the terms and the servers involved. Any run can be sent as a link.
All five safety properties held across 10,000 random runs with compaction and membership changes active. The app is in English with a complete Indonesian translation. It links RaftScope and the paper, and claims only the switches and the checking as new. I built it in two days in August 2026.
Under the hoodTechnical detail for engineers
- The simulation is
(config, seed, actions, ablation flags) → EventTrace, byte-identical everywhere. A priority queue drives the virtual clock; ties break on an explicit sequence number. NosetTimeoutin simulation logic, no floats. - Each server is
step(state, input, config) → { state, outbox, timers }, with the seeded PRNG (lib/sim/prng.ts) threaded through state. lib/invariantsimports only types fromlib/raft. It checks Election Safety, Leader Append-Only, Log Matching, Leader Completeness and State Machine Safety.- All seven ablation flags live in
lib/raft/rules.ts, each consulted at one named call site. Snapshotting has no toggle, because Figure 13 rules 6 vs 7 are about liveness, not safety. - Rules carry comments such as
// Figure 2, AppendEntries RPC, receiver rule 2. - Compaction (§7, Figure 13) forced the log into a bundle of held entries plus a snapshot point, indexed only through
lib/raft/log.ts. It is off by default (snapshotThreshold: 0) so older fixtures keep their exact traces. Chunked snapshot transfer is not modelled. - Membership changes (§6, joint consensus) replaced
majority(n)withhasQuorum(configuration, predicate), requiring majorities of both halves. The §6 "minimum election timeout" rule became aheardFromLeaderflag cleared by the election timer. - Figure 8 exists twice: an exact test in
tests/figure8with a director that replaces only the network, and a playable scenario that takes an extra election or two. - Contrast audit raised secondary text from 2.63:1 to 5.08:1. Node roles use shape as well as colour.
- Simulation runs in a Web Worker. CI runs Figure 2, Figure 13, §6, determinism, Figure 8, ablation and fuzz suites; fuzz gates the deploy. Default 2,000 seeds per run, configurable via
FUZZ_RUNS. - The project was called Mufakat through M0–M7 and was renamed, with the default locale flipped to English, on the last day.
- Three runtime dependencies (Next.js 14.2, React, React DOM). 149 KB JS gzipped on first load against a 250 KB budget. Service worker generated from the export.
- 161 tests in 12 suites: 49 Figure 2 fixtures, 23 compaction, 23 ablation, 16 membership, 38 determinism, 5 Figure 8, 7 fuzz. ~11,500 lines of TypeScript, 29 commits from 4 to 5 August 2026.
Screenshots
Hiring, or building something similar?
I'm open to full-time roles and select freelance work.