Engineering Atlas › System Design Interviews

Distributed systems topics interviewers probe

14 min read · last reviewed 2026-10-17

Open in the interactive app: practice, quiz, mock interview →

In one minute

How it works

Consistency, in interview language

Agreement and coordination

Consensus lets a group agree on a sequence of values despite crashes, as long as a majority is alive and can talk. Raft does it by electing a leader per term; the leader appends entries to its log and replicates them, and an entry is committed once a majority stores it. Use it through a service: etcd or ZooKeeper for coordination, or a database built on it (Spanner, CockroachDB, TiDB, Kafka's KRaft controller). For transactions across services, two-phase commit gives atomicity but blocks if the coordinator fails mid-protocol; sagas with compensating actions trade atomicity for availability and are the usual interview answer across service boundaries.

Failure handling

What to say when

Common mistakes

Down the stack

Layer 1The contract

Linearizability promises that each operation appears to take effect atomically at some instant between its invocation and its response, and all clients agree on that order. Raft promises safety: once an entry is committed it is present in the log of every future leader, so it survives as long as a majority of servers keeps its disk. It promises liveness only when a majority can communicate and timing is reasonably stable. A lease promises that at most one holder believes it holds the lease at a time only if clocks advance at similar rates; it never promises that the holder notices expiry promptly, which is why fencing exists.

Layer 2The mechanism

Raft has two main RPCs. RequestVote(term, candidateId, lastLogIndex, lastLogTerm) is sent by a follower whose randomised election timeout (the paper suggests 150 to 300 ms, Raft paper) expired; a server grants at most one vote per term and only to a candidate whose log is at least as up to date. AppendEntries(term, leaderId, prevLogIndex, prevLogTerm, entries[], leaderCommit) both replicates and acts as a heartbeat; a follower rejects it if its entry at prevLogIndex has a different term, and the leader backs up until logs match. The leader advances commitIndex when a majority has matchIndex at or beyond an entry from its current term; it never commits an older-term entry by counting replicas alone (section 5.4.2 of the paper). etcd builds leases on top: a lease has an ID and TTL, keys attach to it, and every key carries a mod_revision from the cluster-wide revision counter, which serves as a natural fencing token. etcd's own lock API does not pass that check to your storage for you, which is exactly the gap Jepsen measured. ZooKeeper offers the same through ephemeral sequential znodes and the zxid. A fenced storage service keeps the highest token seen per resource and rejects any write with a smaller one.

Layer 3The machine

A Raft entry is not acknowledged until it is fsynced to the follower's WAL, so commit latency is one network round trip to the fastest majority plus one disk flush. That is why etcd's guidance asks for low-latency disks and warns about slow WAL syncs: p99 wal_fsync_duration_seconds should stay under 10 ms and backend commits under 25 ms (etcd FAQ). Leader heartbeats default to 100 ms in etcd with a 1,000 ms election timeout (etcd tuning), so a crashed leader is replaced in roughly one to two seconds. Process pauses break timing assumptions: a stop-the-world GC pause of a few seconds, a VM migration, or heavy swapping can freeze a lease holder past its TTL without it knowing. Clocks drift: NTP usually keeps servers within milliseconds, but a step correction can move wall time backward. On the network, Linux's minimum TCP retransmission timeout defaults to 200 ms (recent kernels expose it as the tcp_rto_min_us sysctl, and a per-route rto_min overrides it, Linux kernel docs), so a single lost packet can add that much latency, which is why timeouts below a few hundred milliseconds trigger false failovers.

Why it's built this way

Machines fail independently, so state is replicated. Replicas can disagree, so they need an agreed order, which requires a majority to overlap any two decisions. Waiting for a majority costs a round trip and a disk flush, so consensus is used for small critical state, while bulk data uses cheaper replication. Failure detection relies on timeouts that cannot distinguish slow from dead, so leases expire and a new leader may coexist briefly with an old one that has not noticed. Storage must therefore reject the old leader's writes, and fencing tokens make that check cheap.

Diagram

sequenceDiagram
    participant A as Client A
    participant L as Lock service
    participant B as Client B
    participant S as Storage
    A->>L: acquire lease
    L-->>A: token 33
    Note over A: GC pause, lease expires
    B->>L: acquire lease
    L-->>B: token 34
    B->>S: write with token 34
    S-->>B: ok (max token 34)
    A->>S: write with token 33
    S-->>A: rejected, stale token

Worked example

A job scheduler must run each of 2 million scheduled jobs at most once per trigger, across a fleet of 30 workers in one region.

Coordination: one leader assigns job partitions. Leadership is a 10-second etcd lease renewed every 3 seconds. With a 3-node etcd cluster spread over three AZs, a write commits in about 2 to 4 ms (one cross-AZ round trip plus an fsync). The leader writes assignment changes to etcd only, about one write per second, so etcd is far from its limits.

Execution: each trigger is a row in a jobs table with (job_id, fire_at, state, owner_token). A worker claims it with a conditional update: UPDATE ... SET state='running', owner_token=? WHERE job_id=? AND fire_at=? AND state='pending'. Only one update can succeed, so a job is claimed once even if two workers race.

Failure: a worker claims a job and then stalls for 40 seconds. The leader sees its heartbeat lapse and re-queues the job with a new token. When the stalled worker wakes and tries to record completion, its conditional update on the old token matches zero rows. Side effects such as sending an email carry the job_id and trigger time as an idempotency key, so even if both executions call the email service, one email goes out.

In the wild

Trade-offs

OptionStrengthsWeaknessesChoose when
Consensus store (etcd, ZooKeeper)Linearizable, fault tolerantLow throughput, majority neededLeader election, locks, config
Leader-follower async replicationFast writes, simpleCan lose recent writes on failoverMost OLTP with tolerable RPO
Leaderless quorumsAvailable, tunable per requestConflicts, read repair, complexityHigh-write, partition-tolerant data
Two-phase commitAtomic across participantsBlocks on coordinator failure, latencyInside one database or tightly owned stores
SagaAvailable, service-friendlyNo isolation, compensations neededWorkflows across services

Pitfalls in production

Leadership lens

Check yourself

  1. Why can a lease-based lock let two clients act as holder at the same time?

    Show answer

    The old holder can pause or have a slow clock and keep acting after its lease expired while the service grants a new lease, so only a fencing check at the resource prevents conflicting writes.

  2. Why does a Raft leader only count a majority for entries from its own term when advancing the commit index?

    Show answer

    An entry from an older term stored on a majority can still be overwritten by a future leader in some histories; committing a current-term entry implicitly commits all earlier ones safely.

  3. A five-node etcd cluster loses two nodes. Can it accept writes? What about three?

    Show answer

    With two lost, three of five remain, a majority, so yes; with three lost it cannot form a majority and stops accepting writes.

  4. How do you get effectively exactly-once processing from a queue that delivers at least once?

    Show answer

    Make the consumer idempotent, for example by recording processed message IDs or using conditional writes in the same transaction as the side effect.

Sources and further study

Primary

Systems docs

Books

Other curricula

Watch

Free resources

Open in the interactive app: practice, quiz, mock interview →