The idea: N copies, wait for W on a write, ask R on a read

A leaderless store like Dynamo, Cassandra or Riak keeps each key on N replicas, here N = 3: A, B and C, the key's preference list on the hash ring. Any node can act as the coordinator of a request. A write is sent to all N replicas, but the coordinator tells the client OK as soon as W of them have acknowledged it. A read asks R replicas and returns the newest value among their replies.

Two panels with replicas A, B, C. Left, W = 2 and R = 2: the write reached A and B, the read asked B and C, and they share B, so the read sees version 2. Right, W = 1 and R = 1: the write reached only A, the read asked only C, they share nothing, and the read returns the stale version 1
With R + W > N the replicas a read asks always include one that took the last write; with R + W ≤ N they may not.

The page plays the worst case that W and R allow, so every run is the same. A write lands on only the first W replicas in the order A, B, C; the other PUTs are drawn as lost (red ✗). A read asks the first R replicas in the order C, B, A, the ones the write reached last. Real networks usually deliver the other PUTs a moment later, but the guarantee has to hold even when they don't.

Versions: the highest one wins

Every value carries a version. Here it is a number the coordinator picks for each write, like a timestamp, so the replica boxes show x = 20, version 2. When R replies come back with different versions, the coordinator keeps the highest one. Green replicas hold the newest version written so far, orange ones are stale. The history table marks a read STALE when it returns something older than the newest write the client was told succeeded.

Why R + W > N works

A write that succeeded is on at least W replicas. A read asks R replicas. If R + W > N, the two sets cannot be disjoint: they share at least one replica, and that replica has the new version, which is the highest one in the replies (Demo 1: W = 2, R = 2). With W = 1, R = 1 the write can sit on A while the read asks C (Demo 2: a stale read). The cost is availability and latency: a bigger W or R needs more live replicas and waits for a slower one.

N = 3R + W > N?writes work withreads work withtypical use
W = 1, R = 1no (2): stale reads2 replicas down2 replicas downfastest; caches, metrics
W = 2, R = 2yes (4)1 replica down1 replica downthe usual quorum (Cassandra QUORUM)
W = 3, R = 1yes (4)no replica down2 replicas downread-heavy data
W = 1, R = 3yes (4)2 replicas downno replica downwrite-heavy data

Read repair

When the replies disagree, the coordinator already knows which replicas are behind: the ones that answered with an older version. After answering the client, it sends them the newest version. This is read repair. In Demo 3 a write with W = 1 reaches only A. A read with R = 3 sees versions 1, 1 and 2, returns version 2 and repairs B and C, so a later read with R = 1 from C is up to date. Read repair only fixes keys that are read; anti-entropy (replicas comparing Merkle trees in the background) fixes the rest.

A replica goes down

With C down, a write with W = 2 still succeeds on A and B, and a read with R = 2 asks B and A (Demo 4). With W = 3 only two acks can come back, so the write fails (Demo 5). But A and B keep the new version: the coordinator does not roll it back. A later read may return a value whose write the client was told had failed.

Sloppy quorum and hinted handoff

Dynamo prefers to accept the write. With a sloppy quorum, a write meant for a down C goes to D, the next healthy node on the ring, with a hint: "this belongs to C". D's ack counts toward W, so W = 3 succeeds with C down. When C comes back, D sends it the write and deletes the hint: hinted handoff (Demo 6).

Three stages. 1: C is down; the write of version 2 goes to A, B and to D with a hint for C, and three acks make W = 3. 2: C recovers still holding version 1. 3: D hands version 2 to C and deletes the hint; A, B and C all hold version 2
D holds C's copy while C is down and hands it over when C returns.

The price: the W nodes that acked are no longer the key's own replicas, so R + W > N no longer promises overlap. A read that asks A, B and C only can miss a write whose third copy sits on D. Cassandra does not count hints toward the consistency level (except ANY); Riak lets the client require primaries with pw and pr.

Quorums are not linearizability

Even with R + W > N a quorum store is not a single copy. A failed write can stay on the replicas that took it (Demo 5). Two clients can write the same key at once; with versions picked by clock, one acknowledged write silently loses (last write wins), and Dynamo and Riak keep both as siblings with vector clocks instead (the CAP page shows both). A read can also race with a write in progress: one reader sees the new value, a later one the old. For linearizable reads and writes a store needs consensus, as in Raft.

In real systems

systemW and Rversions and repair
Cassandraconsistency level per request: ONE, QUORUM, ALL, LOCAL_QUORUMtimestamp per cell (last write wins), read repair, hints, Merkle-tree repair
Riakn_val, w, r, pw, pr per bucket or requestvector clocks / dotted version vectors, siblings, read repair, active anti-entropy
Dynamo (2007 paper)N, R, W per application, typically (3, 2, 2)vector clocks, sloppy quorum, hinted handoff, Merkle trees

See also The CAP Theorem (quorums during a partition), Consistency Patterns (eventual, causal and strong), Consistent Hashing (how the preference list and the next node D are chosen), Merkle Trees and Anti-Entropy (repairing replicas nobody reads), CRDTs (merging concurrent writes without siblings), Lamport and Vector Clocks (ordering versions) and Primary–Replica Replication (the leader-based alternative).

See also Leader-based vs Leaderless Replication: the same 3 replicas next to a single-leader cluster, with a leader failover pause and a lost acknowledged write.

See also Object Storage: instead of N full copies, an object store cuts each object into 4 data + 2 parity shards and rebuilds lost ones on read.

What the page leaves out

Timing: real PUTs and GETs arrive at different moments and the page always shows the worst case instead. More than one key, concurrent writers and vector clocks, digest reads (Cassandra asks one replica for the data and the others only for a hash), speculative retries, read repair that runs in the background or not at all, failure detection (how the coordinator learns C is down), hints that expire, more than one node failing, and data centers (LOCAL_QUORUM, EACH_QUORUM).