Skip to main content
distributed systems

Leader election

10 min read
Fully authored

The general problem: how do N machines pick one boss, and how do they replace it when it dies?

Imagine 10 servers running the same code. They share a database. They need to run a nightly cron. If all 10 run the cron, you charge every customer 10 times. If none of them does, you don't bill anyone. You need exactly one to run it. Which one? And what happens when that one crashes halfway through?

This is the leader election problem — the distributed version of "pick a boss." It sounds simpler than consensus. It isn't. Every solution has to answer three questions: (1) How do we pick a leader when there isn't one? (2) How do we detect the leader has died? (3) How do we prevent two nodes from thinking they're both leader at the same time ("split brain")?

There are 4 industrial answers to these questions: Bully (Garcia-Molina, 1982), Ring (Chang & Roberts, 1979), Raft-style randomized timeout (Ongaro, 2014), and Lease-based (Chubby / etcd). Each makes a different trade-off. Every production system picks one.

The four industrial patterns

Bully
Garcia-Molina · 1982
Idea: Highest priority node wins
✓ Pros: Deterministic, simple
✗ Cons: O(N²) messages, fragile to false-failure detection
Ring
Chang & Roberts · 1979
Idea: Pass token clockwise; largest ID wins
✓ Pros: O(N) messages
✗ Cons: Broken if any node in ring dies mid-election
Raft (randomized timeout)
Ongaro · 2014
Idea: Random timeout → candidate → majority vote
✓ Pros: Battle-tested, provably safe, easy to explain
✗ Cons: Requires majority (2f+1)
Lease-based
Chubby · 2006
Idea: Time-limited leadership grant; renew or lose it
✓ Pros: Simple single-op mental model
✗ Cons: Requires clock synchronization

The Bully algorithm — deterministic priority

Garcia-Molina's 1982 algorithm. Every node has a unique priority ID (usually just a number). The rule is stupid-simple: the highest-priority live node wins. If you notice the leader is gone, you send an ELECTION message to every node with higher priority than you. If any of them respond, they "bully" you out — one of them takes over the election. If none respond, you're the highest live node and you declare yourself leader with a COORDINATOR message.

Bully election — step 1 of 6
5 nodes with priorities 1-5. Watch how the highest live wins.
N1N2N3N4N5LEADER
Steady state — 5 nodes with priorities 1-5. Node 5 (highest priority) is leader.

Bully is deterministic (given who's alive, exactly one node wins) but chatty — worst case is O(N²) messages. It relies on reliable failure detection — if you incorrectly think a higher-priority node is dead, you start an election it'll interrupt. Not great for large clusters or unreliable networks.

The Ring algorithm — pass the token

Chang & Roberts 1979. Every node knows the address of the next node in a logical ring. When a node notices the leader is gone, it starts an election by passing an ELECTION message with its ID clockwise. Every receiver replaces the message's ID with its own if higher, then forwards. When the message returns to the initiator, the highest ID is the winner. A second pass carries the winner's ID as the COORDINATOR announcement.

Ring is O(N) messages — much cheaper than Bully. But it's fragile: if any node in the ring dies mid-election, the message never returns. Real deployments use ring only for small, stable-membership clusters (Cassandra used it in the past for certain internal elections).

The Raft-style randomized timeout

The pattern we saw in the Consensus concept. Every follower waits 150-300ms for a heartbeat. If it doesn't come, follower becomes candidate, bumps its term, votes for itself, requests votes from others. Majority wins. Randomization prevents split votes. This is what etcd, Consul, CockroachDB, TiKV, and Kafka KRaft all use — it's the modern default.

Two properties are key: monotonic terms (a higher term always beats a lower one, so stale leaders auto-demote when they see a higher term) and random timeouts (spread out election attempts so exactly one candidate wins per round with high probability).

The Lease-based approach

Popularized by Chubby (Google, 2006) and copied by etcd, ZooKeeper, and every modern coordination service. A leader holds a lease — a time-limited grant of leadership, say 10 seconds. The leader must renew the lease before it expires; if it fails to renew (crash, network partition), the lease expires and any other node can acquire it.

Lease-based leader election — step 1 of 6
3 nodes competing for a 10-second lease. Watch what happens when the leader can't renew.
etcd / ChubbyLease held by: A100% lease remainingALEADERBC
Node A just acquired the lease. It's leader for 10 seconds. It will renew every 3 seconds to stay leader.

The genius of leases is that they turn leader election into a single atomic operation: acquire the lease. Whoever gets the lease is leader. If nobody has the lease, someone can take it. Split brain becomes impossible if you respect the lease timeout — because when leader-A's lease expires, leader-A must stop acting as leader (because it can't know if someone else already took over). This is why leases require clock sync — you're trusting the clock to tell you when your lease is up.

The split-brain trap

Every leader election protocol has to prevent split brain — two nodes simultaneously believing they're leader. The failure modes are subtle:

  • Bully — Assumes failure detection is reliable. If node A thinks node B (higher priority) is dead because of a network hiccup, A elects itself. When B is reachable again, both think they're leader.
  • Ring — Same failure mode as Bully, plus the election message can get lost mid-ring.
  • Raft — Prevents split brain via terms: a leader in term N stops accepting writes the moment it sees term N+1. But it needs a stable majority to elect a new leader — minority partitions can't elect.
  • Lease-based — Prevents split brain via clock: leader stops acting as leader when its lease expires. Needs clock synchronization (bounded drift).
Failure scenarioBullyRingRaftLease
Leader crash + network healsMay split-brain if failure detector is unreliableSame issue as Bully; election msg can be lostSafe — old leader sees higher term, steps downSafe — old leader's lease expired, it stops acting
Network partition (minority side)Both sides may elect leaders — split brainBroken — election msg loops in one partitionSafe — minority can't get quorum, can't electSafe — minority side can't acquire lease
Clock skew between nodesN/A — doesn't use clocksN/AN/A — uses monotonic terms, not wall-clockUNSAFE if drift > lease/2 — split brain possible
Slow GC pause on leaderN/AN/ASafe — new term wins on return; old is demotedSafe if GC pause < lease TTL; else split brain

Applied in real systems

Kubernetes
Deep dive

Kubernetes — lease-based leader election

Every controller (kube-scheduler, kube-controller-manager, cloud-controller-manager) uses etcd leases via the client-go leaderelection package. Lease duration defaults to 15s, renewal every 10s. Reader can inspect kubectl get lease -n kube-system to see who holds each one.

Read the deep dive →
HDFS NameNode
Deep dive

HDFS — ZKFC leader election

Two NameNodes (Active + Standby). ZooKeeper Failover Controller (ZKFC) watches both. When the Active dies, ZKFC on the Standby side detects it via ZooKeeper ephemeral znode expiry and promotes the Standby to Active. This is a hybrid Raft-consensus (in ZK) + observer-pattern election.

Read the deep dive →
Postgres Patroni
Deep dive

Postgres HA — Patroni with etcd/Consul

Patroni is the industry-standard Postgres HA tool. Every Postgres node runs a Patroni sidecar that uses etcd (or Consul, or ZooKeeper) leases to decide who's the primary. When the primary dies, its lease expires, a standby acquires the lease, is promoted, and replication flips.

Read the deep dive →
MongoDB
Deep dive

MongoDB — replica set primary election

MongoDB replica sets use a Raft-style election (renamed "protocol version 1"). Every replica set has 1 primary and N secondaries. When the primary is unreachable, secondaries vote. The one with the highest priority + freshest oplog wins.

Read the deep dive →
Redis Sentinel
Deep dive

Redis Sentinel — quorum-based failover

Sentinel is Redis's HA solution (before Redis Cluster was mature). N Sentinel processes monitor Redis instances. When a majority of Sentinels agree the master is down, they elect one Sentinel to perform the failover — promote a slave, reconfigure the others.

Read the deep dive →
Chubby
Deep dive

Google Chubby — the lease reference

Burrows (OSDI 2006). Every internal Google service that needed leader election acquired a Chubby lock (which is a lease). Google BigTable's tablet server election runs through Chubby. The paper is the origin of the modern lease-based leader-election pattern.

Read the deep dive →

Key takeaways

  • 4 industrial patterns: Bully (deterministic priority), Ring (token-pass), Raft (randomized timeout + terms), Lease-based (time-limited grant).
  • Bully and Ring are historically important but rarely used in modern production — they rely on reliable failure detection.
  • Raft-style is the default for consensus-based systems (etcd, CockroachDB, Kafka KRaft).
  • Lease-based is the default for coordination services (Chubby, etcd, Kubernetes). Simpler mental model, requires clock sync.
  • Every protocol must prevent split brain — the scenario where two nodes both believe they're leader. Terms (Raft) or leases (Chubby) are the two mechanisms that actually work at scale.
  • Leases need bounded clock drift. If clocks disagree by more than the lease duration, split brain becomes possible.

References

  • Chang & Roberts (1979) — "An Improved Algorithm for Decentralized Extrema-Finding in Circular Configurations of Processes." The Ring algorithm.
  • Garcia-Molina (1982) — "Elections in a Distributed Computing System." The Bully algorithm.
  • Burrows (2006) — "The Chubby Lock Service." OSDI 2006. The lease-based reference.
  • Ongaro & Ousterhout (2014) — The Raft paper.
  • Kubernetes client-go leaderelection package source code — the industrial implementation of etcd-lease-based election.

Practice what you just read

Every foundation concept has a companion quiz to close the loop.