One inequality —
W + R > N— that lets you dial consistency, latency, and availability per query.
Prerequisites: Replication, Consistency Models Time to read: ~18 minutes
Data is on 3 replicas. A client writes.
You want a knob, not a binary. Quorums are that knob.
N = number of replicas
W = replicas that must acknowledge a WRITE before it's considered successful
R = replicas that must respond to a READ before you return an answer
If W + R > N → the read set and the write set MUST overlap
→ at least one responding replica has the latest write
🧠 The intuition, which is worth being able to draw: with N=3, W=2, R=2 — you wrote to 2 of 3 and read from 2 of 3. By the pigeonhole principle, those sets share at least one replica. That replica has the new value, so the read sees it (using version numbers to pick the newest of the responses).
Replicas: [A] [B] [C]
Write to: ✓ ✓ (W=2)
Read from: ✓ ✓ (R=2)
↑ B is in both sets — it has the latest value
📐 Common configurations:
| N | W | R | Property |
|---|---|---|---|
| 3 | 2 | 2 | ✅ Strong-ish; survives 1 failure. The standard default. |
| 3 | 1 | 1 | ⚡ Fastest, most available; eventually consistent |
| 3 | 3 | 1 | Fast reads, but any node down blocks all writes |
| 3 | 1 | 3 | Fast writes, but any node down blocks all reads |
| 5 | 3 | 3 | Strong; survives 2 failures |
| 5 | 1 | 1 | Maximum availability, weakest guarantee |
🚨 Note rows 3 and 4. W=N or R=N means a single unavailable replica breaks that operation
entirely. Extremes are almost always wrong — you gave up the fault tolerance that replication
existed to provide.
The point is that you tune them per workload — and often per query.
Read-heavy (most systems): W=2, R=1 with N=3 gives fast reads at the cost of possible staleness.
Or W=3, R=1 if you must have fresh reads and can tolerate fragile writes.
Write-heavy (logging, telemetry): W=1, R=3 — writes never block, reads pay the cost. Or just
W=1, R=1 if eventual consistency is fine, which for telemetry it usually is.
Balanced: W=2, R=2 with N=3. This is the right default, and the one to state unless you have
a reason otherwise.
Per-query tuning is the real advantage:
Payment record: QUORUM write, QUORUM read → correctness
Product catalogue: ONE write, ONE read → speed, availability
User session: QUORUM write, ONE read → durable, fast to check
🎙️ “I’d default to quorum on both sides, then relax to ONE for the catalogue reads where staleness is harmless and we want the lower latency and better availability.”
W + R > N does NOT give youThis is the most important section in the chapter, and the most common overclaim in interviews.
Quorums do not give you linearizability. They give you “you’ll probably see the latest committed write,” which is meaningfully weaker. The gaps:
1. Concurrent writes. Two clients write simultaneously to overlapping quorums. Which is “latest”? You need conflict resolution — vector clocks, or last-write-wins with all its clock problems.
2. Partially-failed writes. A write reaches 1 of 3 replicas and then the client crashes. It never succeeded (W=2 not met), so the client got an error — but that value now exists on one replica and may surface in a later read. A write that “failed” can still become visible.
3. Sloppy quorums. See below — the overlap guarantee doesn’t hold.
4. Read repair races. Concurrent reads and repairs can interleave in ways that violate ordering.
5. No ordering between operations. Quorums say nothing about the relative order of operations on different keys.
🚨 The correct framing: quorums give you a probabilistic freshness guarantee that’s dramatically better than nothing and dramatically weaker than consensus. If you need real linearizability, you need consensus, not quorums.
🎙️ “Quorum reads and writes get us ‘very likely the latest value,’ not linearizability — concurrent writes and partially-failed writes both break the guarantee. For the operations that genuinely need linearizability, I’d use a consensus-backed store.”
That distinction is a strong senior signal, because most candidates say “W+R>N gives strong consistency” and stop.
Dynamo-style systems add an availability trick with a real cost.
Strict quorum: the W acknowledgments must come from the W nodes that own that key (its “home” nodes on the hash ring).
Sloppy quorum: if some home nodes are unreachable, accept writes on any W reachable nodes, which hold the data temporarily as a hint. When the home node returns, the hint is handed off to it.
⚖️ The trade:
W + R > N no longer implies you’ll see the latest value.Hinted handoff is the recovery mechanism: the temporary holder delivers the data when the real owner returns. Combined with read repair (fix stale replicas discovered during a read) and anti-entropy (background comparison using Merkle trees), replicas converge. → Gossip Protocols
🚨 Sloppy quorums are the reason Cassandra and Dynamo are AP rather than CP, and knowing that they break the quorum guarantee — rather than just knowing the term — is the depth signal here.
Both use majorities. They are not the same thing.
| Quorum (Dynamo-style) | Consensus (Raft/Paxos) | |
|---|---|---|
| Leader | None — any node accepts writes | One leader accepts all writes |
| Guarantee | “Probably the latest value” | Linearizable |
| Concurrent writes | Both accepted → conflict to resolve | Serialized by the leader → no conflict |
| Ordering | None across operations | Total order via the log |
| Write availability | High — no leader to fail | Blocked during elections |
| Throughput | High — no coordination bottleneck | Limited by the leader |
| Complexity | Lower | Higher |
| Examples | Cassandra, DynamoDB, Riak | etcd, ZooKeeper, Spanner, CockroachDB |
🎙️ The one-line distinction: “Quorums tell you how many replicas must respond. Consensus tells you what order things happened in. If you need ordering or linearizability, quorums aren’t enough.”
Latency is the slowest of the W (or R) responses, not the average.
📐 With N=3 and W=2, you wait for the second-fastest replica. With W=3, you wait for the slowest —
which means your write latency is now the p99 of your slowest replica,
and it’s much worse than you’d expect. This is a strong practical argument against W=N.
Multi-datacenter quorums need care. A quorum spanning regions means every write pays a
cross-region round trip (~150 ms). Cassandra’s LOCAL_QUORUM is the standard answer — require a
quorum within the local datacenter only, and replicate asynchronously across regions. You get local
latency and cross-region durability, at the cost of losing recent writes if the whole region fails.
Replica count and durability. N=3 across availability zones is the common default. N=5 for data you really can’t lose. Note that N also determines your storage cost multiplier — N=3 means 3× the disk.
Monitor repair health. Read repair and anti-entropy are what make eventual consistency actually converge. If Cassandra repairs aren’t running (they’re notoriously easy to neglect), replicas drift apart indefinitely and deleted data can resurrect when a stale replica is read.
| Setting | Gain | Cost |
|---|---|---|
W + R > N |
Very likely to read the latest write | Higher latency on both paths |
W=1 |
Fastest writes; survives most failures | Stale reads; write may be lost if that node dies |
R=1 |
Fastest, most available reads | May return stale data |
W=N or R=N |
Strongest for that operation | One node down breaks it entirely |
| Larger N | More durability and fault tolerance | More storage; higher quorum latency |
| Sloppy quorum | Writes succeed during failures | Breaks the overlap guarantee |
LOCAL_QUORUM |
Local latency in multi-region | Recent writes lost if the region fails |
ONE, QUORUM, LOCAL_QUORUM, ALL, EACH_QUORUM) are this
chapter exposed as a per-query parameter, which is why the same cluster can serve
strongly-consistent payments and eventually-consistent analytics.W + R > N gives linearizability. It doesn’t. Name the gaps: concurrent writes,
partially-failed writes, sloppy quorums.W=N or R=N without noticing it destroys fault tolerance.LOCAL_QUORUM.1. See consistency levels in Cassandra. Three-node cluster in Docker. Then:
CONSISTENCY ONE;
INSERT INTO users (id, name) VALUES (1, 'Bilal');
-- Stop a node, then:
CONSISTENCY QUORUM;
SELECT * FROM users WHERE id = 1; -- still works (2 of 3)
-- Stop a second node:
SELECT * FROM users WHERE id = 1; -- fails — no quorum
CONSISTENCY ONE;
SELECT * FROM users WHERE id = 1; -- works again, possibly stale
Watching the same query succeed or fail purely based on consistency level is the clearest possible demonstration of the trade-off.
2. Prove W=1/R=1 is stale. With one node paused, write at ONE, then start the node and
immediately read at ONE in a loop. Count how often you get the old value before read repair fixes
it.
3. Measure the latency cost. Benchmark writes at ONE, QUORUM, and ALL. Plot them. Then
introduce artificial latency on one node (tc netem) and re-measure — watch ALL degrade
catastrophically while QUORUM barely moves. That’s the argument against W=N in one graph.
4. Create a conflict. Partition the cluster, write different values to the same key on each side
at ONE, then heal it. Observe which value survives and work out why — that’s last-write-wins, and
its dependence on clocks.
W + R > N guarantee you read the latest write?