Introduction

Imagine five servers that need to agree on every operation — every database write, every configuration change — even though any server can crash at any moment, and messages between them can be delayed or lost. This is the consensus problem, and it is one of the most fundamental challenges in distributed systems.

For years, Paxos was the standard answer. It works, and it is provably correct — but it is notoriously hard to understand, and harder still to implement correctly. Real-world systems built on Paxos often required the designers to invent their own extensions just to fill in the gaps the original paper left open.

In 2014, Diego Ongaro and John Ousterhout published Raft — an algorithm designed from the ground up with one explicit goal: understandability. They decomposed the consensus problem into three nearly independent sub-problems: leader election, log replication, and safety. The result is an algorithm that engineers can actually hold in their heads and implement correctly.

Raft is now the consensus engine behind etcd (which powers Kubernetes), CockroachDB, TiKV, and dozens of other production systems. It is the algorithm you reach for when you need distributed agreement and you want to be able to reason about what your code is actually doing.

Elect and Replicate

The demo below shows a five-node Raft cluster. Each node is either a Leader (gold), Follower (blue), or Candidate (amber). Click Start Election to kick off a leader election, then Append Entry to add a log entry that replicates to all followers. Try Crash Follower to drop a node and watch the cluster keep working.

<p class="hint">{{hint}}</p>
<div id="cluster"></div>
<div id="log-panel">
  <div class="log-title">{{log_title}}</div>
  <div id="log-entries"></div>
</div>
<div class="status" id="status">{{initial_status}}</div>
<div class="btns">
  <button id="btn-elect" type="button">{{btn_elect}}</button>
  <button id="btn-append" type="button">{{btn_append}}</button>
  <button id="btn-crash" type="button" class="ghost">{{btn_crash}}</button>
  <button id="btn-reset" type="button" class="ghost">{{btn_reset}}</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .88rem; color: #444; margin: 0 0 .8rem; line-height: 1.45; }
#cluster { display: flex; gap: 10px; margin: .5rem 0 .8rem; flex-wrap: wrap; }
.node { width: 80px; padding: 8px 4px; border-radius: 10px; text-align: center;
        border: 2px solid transparent; transition: all .25s; user-select: none; }
.node-name { font: 700 13px ui-monospace, monospace; margin-bottom: 3px; }
.node-role { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.node-term { font-size: 11px; color: #666; margin-top: 2px; }
.node.leader { background: #ffe680; border-color: #c8a000; }
.node.leader .node-role { color: #7a5f00; }
.node.follower { background: #dbeafe; border-color: #3b82f6; }
.node.follower .node-role { color: #1e40af; }
.node.candidate { background: #fde68a; border-color: #d97706; }
.node.candidate .node-role { color: #92400e; }
.node.crashed { background: #f1f5f9; border-color: #94a3b8; opacity: .55; }
.node.crashed .node-role { color: #64748b; }
#log-panel { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px;
             padding: 8px 10px; margin-bottom: .7rem; min-height: 44px; }
.log-title { font: 700 12px system-ui; color: #64748b; text-transform: uppercase;
             letter-spacing: .06em; margin-bottom: 6px; }
#log-entries { display: flex; gap: 6px; flex-wrap: wrap; }
.log-entry { padding: 4px 8px; border-radius: 6px; font: 600 12px ui-monospace, monospace;
             border: 1.5px solid #3b82f6; background: #eff6ff; color: #1d4ed8; }
.log-entry.committed { border-color: #16a34a; background: #f0fdf4; color: #166534; }
.status { font-size: .95rem; font-weight: 600; margin: .4rem 0; min-height: 1.4em; }
.status.ok { color: #166534; }
.status.warn { color: #92400e; }
.status.info { color: #1e40af; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .3rem; }
button { font: 600 13px system-ui; padding: .42rem .85rem; border-radius: 8px; cursor: pointer;
         border: 1.5px solid #1d3557; background: #1d3557; color: #fff; }
button.ghost { background: #fff; color: #1d3557; }
button:disabled { opacity: .45; cursor: default; }
// Code not found

Notice the key insight: as long as a majority of nodes (three out of five here) are alive and can communicate, the cluster remains available. The leader replicates each entry to followers, and an entry is committed only once a majority has acknowledged it — guaranteeing it survives any minority of crashes.

The Real Complexity

Raft looks clean, but it lives inside some deep impossibility results.

  • The FLP impossibility (1985): Fischer, Lynch, and Paterson proved that in an asynchronous network — where messages can be delayed by any finite amount — no deterministic consensus algorithm can always make progress. Every consensus protocol, including Raft, handles this by assuming that delays are usually bounded (eventually synchronous), and by timing out when they are not.
  • The CAP theorem: When a network partition splits a cluster into two halves, a system must choose between consistency (all nodes see the same data) and availability (every request gets a response). Raft chooses consistency: if a leader cannot reach a majority of nodes, it stops accepting writes. The minority side simply waits.
  • Safety is formally proven: Raft's key safety property — the Log Matching Property — guarantees that if two logs contain an entry with the same index and term, then all entries up to that point are identical. This was verified formally with the TLA+ model checker, giving engineers strong guarantees beyond what testing alone provides.
  • Liveness requires timing: Raft makes progress only when the network is eventually synchronous and election timeouts are chosen well. A leader whose heartbeats are consistently slower than followers' timeouts will trigger repeated re-elections. In practice, timeouts of 150–300 ms work in most datacenters.

Raft did not make consensus easy — it made it understandable. The hard limits still apply: you cannot avoid the cost of a round-trip to a majority, and you cannot guarantee progress under arbitrary network behavior. What Raft gives you is a clean mental model for reasoning about those tradeoffs, and a proven-correct implementation path. Compare this to P vs NP — another boundary where a problem is tractable to verify but the full solution space hides irreducible cost.

Where It Matters

Raft's understandability premium has made it the go-to consensus algorithm for a generation of distributed systems:

  • Kubernetes via etcd: etcd is the distributed key-value store that holds all of Kubernetes' cluster state — which pods are running, which nodes exist, which services are configured. It uses Raft to ensure that this state is consistent across all etcd replicas, even if some crash.
  • CockroachDB and TiKV: These distributed SQL databases use Raft (one instance per shard) to replicate each range of data. Every write goes through Raft, giving the database the same strong consistency guarantees as a single machine while surviving node failures.
  • Service discovery and configuration: Systems like Consul use Raft to maintain consistent configuration data across a cluster, ensuring all services see the same view of which endpoints are healthy.
  • Distributed locks and coordination: Any time multiple services need to coordinate — electing a primary, acquiring a distributed lock, or performing a two-phase commit — Raft provides the reliable ordering guarantee that makes it safe.

The common thread: whenever you need a group of machines to behave as reliably as a single machine, but without a single point of failure, Raft is the mechanism that makes it possible. See also load balancing for how work gets distributed once consensus keeps the cluster in sync.

Conclusion

Raft did not discover new theoretical ground — Paxos already solved distributed consensus. What Raft discovered is that understandability is a correctness property. An algorithm engineers cannot understand is an algorithm they will implement wrong, and a wrong consensus algorithm is far worse than a slow one: it silently corrupts your data while appearing to work.

By decomposing the problem into leader election, log replication, and safety — and by making every design choice explicit and motivated — Raft gave engineers something Paxos never quite managed: a system they could trust because they could reason about it.

The FLP impossibility and CAP theorem are still there. You still pay the cost of a round-trip to a majority. You still stop writing during a partition. But now you know exactly why, and exactly what your system will do. In distributed systems, that kind of clarity is worth more than most optimizations. See also Nash equilibrium for another domain where the right framing of a problem changes what becomes solvable.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/raft/Content licensed under CC BY-NC 4.0.