System designCore9 min

Consensus & leader election

How a handful of machines agree on one answer, and on one order of events, while some of them crash and messages go missing: why a majority, how a leader is chosen, and why you should never build this yourself.

1 · The problem

Several machines must settle on one answer, even if some crash

Three servers each keep a copy of a bank account's ledger, so that losing one server loses nothing. Two requests arrive at almost the same moment: deposit $100 and withdraw $120, on an account holding $50. Applied in one order, the withdrawal succeeds. In the other, it bounces. Every copy must apply them in the same order, or the copies disagree about your money.

The same two requests, applied in different orders. Server 1 says the account holds $30; server 2 says $150 and a bounced withdrawal.

Consensus is getting several machines to agree on one value, even though some of them may crash and messages may be delayed or lost. Agreeing once is useful; agreeing again and again on "what comes next" gives you a shared, ordered log of changes, which every copy applies in the same order. That covers most of what systems need consensus for:

  • One leader: exactly one machine in charge at a time.
  • One order of changes: the replicated ledger above.
  • Locks and settings: who holds a lock, which database is primary, what the current configuration is.

2 · The trade

Never wrong, and eventually done: you cannot be sure of both

Two kinds of promise are at stake:

  • Safety: nothing bad ever happens. The machines never decide two different things.
  • Liveness: something good eventually happens. They do reach a decision.

It has been proved that when messages can be delayed without limit, no deterministic protocol can guarantee both, if even one machine might crash. A machine that has gone quiet might be dead or just slow, and waiting for it forever means never deciding, while giving up on it risks deciding without its vote.

A consensus protocol may stall, but it never decides two different things. Real protocols keep safety absolutely and treat liveness as "almost always". They use timeouts and randomness to move on when the network behaves reasonably, which is nearly all the time. During a bad partition, they pause rather than guess.

Promise

Means

During a bad partition

Safety

The machines never decide two different things

Kept, always

Liveness

The machines do reach a decision

Given up for a while: the protocol stalls

3 · Majorities

Any two majorities share at least one machine

The trick at the heart of every consensus protocol: a decision needs the agreement of a majority of the machines. Of five machines, any two groups of three must overlap in at least one machine, because 3 + 3 is more than 5. That machine will not agree to two conflicting things, so two conflicting decisions can never both win.

Machines

Majority

Can lose and keep working

1

1

0

2

2

0

3

2

1

4

3

1

5

3

2

7

4

3

In general, 2f + 1 machines survive f failures. Look at the even rows: four machines survive no more failures than three, and two survive none, yet they cost more and every decision waits for more of them. That is why clusters have odd sizes, usually three or five.

Site A: node 1Site A: node 2Site A: node 3Site B: node 4Site B: node 5link cutSite A: node 1Site A: node 2Site A: node 3Site B: node 4Site B: node 5link cut

Five machines in two sites. When the link is cut, site A still has three of five and carries on; site B knows it is the minority and stops. But lose site A entirely, and site B's two cannot decide anything. Surviving the loss of a whole site needs a third site.

4 · Leader election

Terms and one vote each give at most one leader at a time

Most protocols pick one leader to make proposals, because one machine choosing the order is far simpler than everyone negotiating every entry. The leader sends regular heartbeats. When a follower hears none for a while, it tries to take over:

A's own vote plus B's is a majority of three. C's answer is no longer needed.

Four rules make this safe:

  • Terms. Every election starts a new, higher term number.
  • One vote per term. Each machine votes at most once in a term, so at most one candidate can collect a majority.
  • Random timeouts. Each machine waits a slightly different random time, often a few hundred milliseconds, before standing. So usually one stands alone and wins; if two tie, both wait another random time and try again.
  • Only an up-to-date candidate wins. A machine refuses to vote for a candidate whose log is behind its own, so a new leader always has every decision already made.

And the old leader? If it was only cut off, it still thinks it leads. But it can no longer reach a majority, so nothing it proposes is ever accepted, and the moment it hears a higher term it steps down. The term number does the same job as a fencing token (see Failure detection & split brain).

5 · Replication

A change counts once a majority has written it down

With a leader in place, every change goes through it and into the shared log:

The leader does not wait for the slowest follower. Once a majority has stored the entry, it is committed: applied to the ledger, and the client is told.

Now crash the leader at the worst moment:

  • After a majority stored the entry: it survives. Any new leader needs votes from a majority, which overlaps the majority holding entry 7, and the voting rule means only a machine that has entry 7 can win.
  • Before a majority stored it: it may be lost. That is safe, because the client was never told "done". It retries.

This is the essence of the best-known protocols. Paxos is the older and more famous; Raft was designed later to be easier to understand and to build, and at heart it works as described here.

6 · In practice

Use it for small, critical decisions, and never build it yourself

Consensus is not free. Every change waits for a majority to answer: about a millisecond or two when the machines are in nearby buildings, tens of milliseconds when they are in different regions. So systems use it for small, critical things, such as who is leader, which database is primary, who holds a lock, the current configuration, and let the bulk of the data flow by cheaper means.

Decision

Through consensus?

Why

Who is leader

Yes

Two leaders would accept conflicting writes

Which database is primary

Yes

Small, rare, and must be one answer

Who holds a lock

Yes

Two holders defeat the lock

The current configuration

Yes

Every machine must act on the same settings

The bulk of the data

Usually not

Each change would wait for a majority, so it flows by cheaper means

You will almost never implement it. Small open-source coordination services built on these protocols exist for exactly this job, and many databases run consensus internally for their own replication. Use those. The protocols fit on a page, but real implementations must also handle disks that lie about what they saved, machines joining and leaving, and snapshots of logs that grow forever. Independent testing has repeatedly found subtle bugs even in mature, widely used implementations.

One limit to remember: these protocols assume machines crash; they do not assume machines lie. Tolerating liars is a different, costlier problem that needs at least 3f + 1 machines to survive f of them (see Why distributed systems are hard).

Check yourself

5 questions

1. Why does a consensus decision need a majority rather than, say, any two machines out of five?
2. A team runs consensus on 4 machines instead of 3 "for safety". How many failures can each survive?
3. A partition cuts off the old leader. It still believes it leads. What stops it from doing damage?
4. The leader crashes after writing an entry locally but before any follower stored it. What happens to the entry?
5. Why keep consensus for small, critical data instead of running every user request through it?

Takeaways

Remember this

  • Consensus gets machines to agree on one value, or one order of changes, despite crashes and lost messages.
  • A protocol may stall during a bad partition, but it never decides two different things.
  • Decisions need a majority; any two majorities overlap. 2f + 1 machines survive f failures, so use odd sizes.
  • Terms, one vote each, random timeouts and up-to-date candidates give at most one leader at a time.
  • A change is committed once a majority stores it. Use existing coordination services for small, critical data; never build your own.