The idea: a line of servers, write at one end, read at the other

Chain replication puts the replicas of a key in a line: S1 → S2 → S3. The first server is the head, the last one the tail. A write goes to the head, which applies it and passes it to the next server, and so on down the chain. When the write reaches the tail, every server has it: it is committed, and the tail tells the client OK. A read goes to the tail and returns the tail's value.

Client above a chain S1 head, S2, S3 tail. 1: PUT x=20 goes to S1. 2 and 3: x=20 seq 2 is forwarded S1 to S2 to S3. 4: S3 replies OK to the client. GET x goes from the client to S3. Dashed ack 2 arrows go back from S3 to S2 to S1
A write takes one hop per server and is answered by the tail; a read touches only the tail.

The head gives each write a sequence number (seq), so every server applies the updates in the same order. Each server keeps the updates it has passed on but not yet seen acknowledged in a pending list (the paper calls it Sent). After the tail commits seq 2, an ack 2 travels back up the chain and each server drops seq 2 from its pending list (Demo 1). On the canvas a green server holds only committed updates, an orange one still has pending updates.

Why reads at the tail are strongly consistent

The tail only holds updates that every server in the chain already has. So a value the tail returns can never be lost by a crash, and a later read can never return something older. That makes chain replication linearizable without voting or quorums: one server decides the order (the head) and one server answers (the tail).

A read that arrives while a write is still in flight returns the old value (Demo 2). That is correct: the client has not been told OK yet, so the write has not happened as far as anyone can tell. Once the write reaches the tail, the next read returns the new value.

Reading anywhere else

The head is ahead of the tail: it holds updates that are not committed yet. With read from: head a read can return such a value. In Demo 3 the head returns x = 20, then crashes before forwarding it. x = 20 is gone, and the next read at the tail returns x = 10: the reads went back in time. The client never got OK for x = 20, so its next Write resends it to the new head. CRAQ (chain replication with apportioned queries) lets every server answer reads safely: a server with a pending version asks the tail which version is committed.

Failures and the master

The servers do not repair the chain themselves. A separate master (in practice a small Paxos or ZooKeeper group) watches heartbeats, removes a crashed server and tells the neighbours and the client the new chain.

Three rows. Head S1 fails: chain becomes S2 head, S3 tail; writes only S1 had are lost. Middle S2 fails: chain becomes S1 head, S3 tail; S1 resends what S3 is missing. Tail S3 fails: chain becomes S1 head, S2 tail; what S2 holds is committed
Each of the three crash cases needs a different repair, but none of them loses a write the client was told succeeded.
crashthe masterwhat happens to writes in flight
headmakes the next server the headwrites only the old head had are lost; they were never acked, so the client retries (Demo 3)
middlelinks the predecessor to the successorthe successor reports its last seq; the predecessor resends the rest from its pending list (Demo 5)
tailmakes the predecessor the tailthe new tail already holds them: they are committed now, and it answers the client (Demo 4)

Adding a server

A new server joins at the tail. It first copies the current tail's state, then the master makes it the new tail and tells the old tail to forward to it (Demo 6). A chain of n servers survives n − 1 crashes, but every write takes n hops.

Compared with other replication schemes

chain replicationprimary–replicaquorums (R + W > N)
write goes tohead, then each server in turnprimary, then all replicas in parallelall N replicas, wait for W
write latencyn hops in a rowone round trip to the slowest synced replicathe W-th fastest replica
reads go tothe tailthe primary (or a replica, maybe stale)R replicas
consistencylinearizablelinearizable at the primary onlynot linearizable on its own
a crashmaster reconfigures; a slow server slows every writefailover, possible lost writes with asyncno reconfiguration needed

In real systems

Chain replication appears in the FAWN-KV key-value store, in HDFS's write pipeline (a block's replicas form a pipeline and acks come back along it), in Hibari and in CRAQ-based object stores. Kafka is different: its leader collects followers' fetches in parallel (Kafka replication).

See also Primary–Replica Replication (sync vs async), Quorum Reads and Writes (R + W > N), Leader-based vs Leaderless Replication, Raft (consensus, the kind of protocol the master itself runs) and Consistency Patterns.

What the page leaves out

Timing (failure detection takes a timeout, and the chain is paused while the master reconfigures), more than one key and many clients, batching and pipelining many writes on each link, a crash during reconfiguration, the master's own replication, CRAQ's version queries, the old tail forwarding new updates while a new server copies its state, and servers in different data centers.

On the mind map

Open the Distributed Systems mind mapDistributedSystemsReplication: copies of data · what reads seeReplicationPartitioning: split data over nodesPartitioningTime and membership: order events, know who is aliveTime and membershipConsensus: agree on one value or logConsensusTransactions: one change across many servicesTransactionsMessaging: send events between systemsMessagingKafka internals: a replicated append-only logKafka internalsRedis internals: one thread, data in memoryRedis internalsKubernetes: reconcile desired stateKubernetesResilience and speed: stay up and fast under loadResilience and speedPrimary-replica replicationPrimary-replica replicationasync is fast but can lose writesLeader vs leaderlessLeader vs leaderlessfailover pause vs W-of-N quorumsQuorum reads and writesQuorum reads and writesR + W > N: reads meet the last writeConsistency patternsConsistency patternsweak, eventual, causal, strongCAP theoremCAP theoremin a partition: consistent or availableCRDTsCRDTsmerge in any order, same resultMerkle anti-entropyMerkle anti-entropycompare hashes, sync only what differsSync vs semi-sync vs asyncSync vs semi-sync vs asyncwhat an acked write survives: the RPOChain replicationWrite at head, read at tailOpen the Distributed Systems mind mapDistributed Systemscopies of data · what reads seeReplicationPrimary-replica replicationPrimary-replica replicationasync is fast but can lose writesLeader vs leaderlessLeader vs leaderlessfailover pause vs W-of-N quorumsQuorum reads and writesQuorum reads and writesR + W > N: reads meet the last writeConsistency patternsConsistency patternsweak, eventual, causal, strongCAP theoremCAP theoremin a partition: consistent or availableCRDTsCRDTsmerge in any order, same resultMerkle anti-entropyMerkle anti-entropycompare hashes, sync only what differsSync vs semi-sync vs asyncSync vs semi-sync vs asyncwhat an acked write survives: the RPOChain replicationWrite at head, read at tail
This page on the Distributed Systems mind map · 79 pages in 10 branches · open it to see the whole map and test yourself in recall mode.