System Design
Advanced 13 min read Data at scale

Consistency models and quorums

In one line

Consistency models define what a reader is allowed to see after a write, from linearizable (always the latest) to eventual (latest some time later), and quorums (R + W > N) are the main tool replicated stores use to choose a point on that scale per request.

What it is

When data is copied to several replicas, a read may hit a replica that has not received the latest write. A consistency model is the contract that says which values a read may return. CAP tells you that during a partition you choose between consistency and availability; consistency models describe the many levels in between.

From strongest to weakest, the models you should know: linearizability (every operation appears to happen at one instant between its start and end, so a read after a completed write always sees it); sequential consistency (all clients see operations in one order, but not necessarily real-time order); causal consistency (if A caused B, everyone sees A before B, for example a question before its answer); and eventual consistency (if writes stop, replicas converge, with no promise about when).

There are also client-centric guarantees, which are cheap and often all a product needs: read-your-writes (you always see your own update), monotonic reads (you never see time go backwards across reads), monotonic writes, and writes-follow-reads.

Quorums are how leaderless stores like Cassandra, Riak and Dynamo-style systems tune this. With N replicas, a write waits for W acknowledgements and a read asks R replicas. If R + W > N, every read set overlaps every write set in at least one replica, so the read can find the newest value.

Why interviewers ask

Interviewers use consistency to separate candidates who repeat 'eventual consistency' from those who can say exactly what a user would see. Strong answers name the anomaly they are preventing (a user not seeing their own post, a seat sold twice), choose the cheapest model that prevents it, and know that R + W > N alone is not linearizability.

How it works

  1. 1Choose the replication factor N, commonly 3, with replicas in different racks or availability zones.
  2. 2On a write, the coordinator sends the write to all N replicas and returns success after W of them acknowledge. The rest catch up later.
  3. 3On a read, the coordinator asks R replicas and returns the value with the newest version (timestamp or vector clock).
  4. 4If R + W > N (for N = 3, QUORUM reads and writes mean R = 2, W = 2), the read set and the write set share at least one replica, so the latest acknowledged write is seen.
  5. 5Tune per request: W = 1, R = 1 is fastest and most available but may return stale data; W = 3 (ALL) makes writes fail if any replica is down; QUORUM/QUORUM is the usual balance and tolerates one replica down out of three.
  6. 6Repair stale replicas: read repair (fix replicas that answered with old values during a read), hinted handoff (a neighbour holds writes for a down replica and replays them), and anti-entropy repair using Merkle trees to compare and sync data in the background.
  7. 7Know the gaps: with last-write-wins timestamps, clock skew can drop a write; sloppy quorums (writing to non-home nodes during failures) break the overlap guarantee; and a write that failed to reach W replicas may still be visible on some, so quorums are not linearizable without extra steps such as read repair before returning.
  8. 8For real linearizability, use a leader-based consensus system (Raft or Paxos: etcd, ZooKeeper, Spanner, CockroachDB) or read from the leader of a single-leader database.

Worked example · Cassandra with N = 3 across three zones

  1. Setup: replication factor 3, one replica in each of zones A, B and C. Each replica write takes about 2 ms locally; cross-zone round trips are about 1 ms.
  2. Write with QUORUM: the coordinator sends to A, B, C and returns after 2 acknowledgements, about 3 ms. Replica C is slow and applies the write 50 ms later.
  3. Read with QUORUM right after: the coordinator asks 2 replicas. Even if it picks C (stale) and A (fresh), it compares timestamps and returns A's newer value, then repairs C.
  4. Read with ONE right after: if the request hits C before it has applied the write, the user sees the old value. Here R + W = 1 + 2 = 3, which is not greater than N = 3.
  5. Zone C goes down: QUORUM reads and writes still succeed with A and B (2 of 3). With ALL, every write would fail, so ALL is rarely used.
  6. Two zones down: QUORUM fails (only 1 of 3 left). Now the system must choose: refuse requests (consistency) or drop to ONE (availability). This is CAP in practice.

Picture it

Imagine three notice boards in a college, and a notice is 'posted' once the clerk has pinned it on at least two boards. If you check any two boards, at least one of them must have the newest notice, because two plus two is more than three. Checking just one board is quicker, but you might pick the one that has not been updated yet.

Key patterns

Strong where it matters, eventual elsewhere

When: Mixed workloads, such as payments plus social features

How: Use quorum or leader reads for money, inventory and user-visible own writes; use single-replica reads for counters, feeds and recommendations.

Read-your-writes via session stickiness

When: Users must see their own changes immediately but global strong consistency is too costly

How: Route the user's reads to the leader or their home region for a short window after a write, or pass a version token and wait until the replica has caught up to it.

LOCAL_QUORUM for multi-region

When: Cassandra-style stores across regions

How: Get quorum guarantees inside a region at local latency, and accept asynchronous cross-region replication.

Real-world use

Apache Cassandra and ScyllaDB

Expose per-request consistency levels: ONE, QUORUM, LOCAL_QUORUM (quorum inside one data centre, avoiding cross-region latency), EACH_QUORUM and ALL. LOCAL_QUORUM is the common choice for multi-region deployments.

Amazon DynamoDB

Reads are eventually consistent by default and cost half as much as strongly consistent reads, which you request per call. Global tables replicate across regions asynchronously, and DynamoDB has offered a multi-region strong consistency mode for global tables.

Google Spanner

Provides external consistency (stronger than linearizability across transactions) by using Paxos per shard and TrueTime, GPS- and atomic-clock-backed time with bounded uncertainty, waiting out that uncertainty before committing.

Facebook TAO and read-your-writes

Facebook's social graph cache is eventually consistent across regions, but it routes a user's reads so they see their own writes, because a user not seeing their own comment feels like a bug while a friend seeing it a second late does not.

etcd and ZooKeeper

Use consensus (Raft and Zab) so that writes are linearizable; Kubernetes relies on etcd for this. etcd reads are linearizable by default, with an optional serializable mode that may be stale but is cheaper.

In a project

A social app in India stores posts in a three-region Cassandra cluster (Mumbai, Hyderabad, Singapore). Users complain that after editing a profile bio, refreshing the page sometimes shows the old bio, and support tickets spike after every deploy.

  1. Find the cause: writes use LOCAL_ONE and reads use LOCAL_ONE, so R + W = 2, not greater than 3 local replicas; reads often hit a replica that has not applied the edit.
  2. Decide the real requirement: users must see their own edits (read-your-writes); other users can see the change a few seconds late.
  3. Switch profile writes and reads to LOCAL_QUORUM (W = 2, R = 2 of 3 in the region), which adds about 1 to 2 ms but guarantees overlap inside the region.
  4. Pin each user's session to their home region so their reads do not go to a region where the asynchronous cross-region copy has not arrived yet.
  5. Keep feed and like-count reads at LOCAL_ONE, because slight staleness there is acceptable and these are the highest-volume reads.
  6. Run nodetool repair on a schedule and alert on hinted-handoff backlog after deploys, which was why staleness got worse during rolling restarts.

Impact: Stale-bio complaints drop to near zero, p99 profile latency rises only from 6 ms to 8 ms, and the high-volume feed path keeps its cheap single-replica reads.

Trade-offs

Use it when

  • Quorums: leaderless replicated stores where you want per-request control of latency vs freshness
  • Linearizable (consensus) storage: locks, leader election, unique usernames, seat or stock reservation
  • Causal or read-your-writes: social products where users must see their own actions and replies after the posts they answer
  • Eventual: counters, view counts, feeds, analytics, recommendations

Avoid it when

  • Strong consistency across regions on every request: each write pays a cross-region round trip of 50 to 150 ms
  • Eventual consistency for balances, inventory or anything where two concurrent writers can both 'win'
  • Relying on R + W > N alone for correctness with last-write-wins and unsynchronised clocks
  • ALL consistency level: one slow or dead replica blocks every write

Common mistakes

  • Treating 'consistency' in CAP and the C in ACID as the same thing. ACID consistency means invariants hold; CAP consistency means linearizability.
  • Claiming R + W > N gives linearizability. It gives overlap, but sloppy quorums, clock-skewed last-write-wins and partially failed writes can still produce anomalies.
  • Asking for strong consistency everywhere without saying what it costs in latency and availability.
  • Saying 'eventual consistency' without stating the window (milliseconds or minutes) and what the user sees during it.
  • Ignoring replica lag on read replicas of a single-leader SQL database: a user writes to the primary and then reads stale data from a replica.
  • Forgetting repair: without read repair, hinted handoff and anti-entropy, replicas drift apart permanently.

Interview questions

Quick revision

  • Linearizable > sequential > causal > eventual (strong to weak).
  • Client-centric: read-your-writes, monotonic reads, monotonic writes, writes-follow-reads.
  • Quorum rule: R + W > N means read and write sets overlap.
  • N = 3, QUORUM/QUORUM: R = 2, W = 2, tolerates 1 replica down.
  • W = 1, R = 1: fastest, may be stale.
  • Repair: read repair, hinted handoff, Merkle-tree anti-entropy.
  • Quorums are not automatically linearizable; consensus (Raft, Paxos) is.
  • Multi-region: LOCAL_QUORUM + async cross-region replication.
  • Name the anomaly you prevent, then pick the cheapest model that prevents it.

Check yourself

1. With N = 5 replicas and W = 3, what is the smallest R that guarantees read and write sets overlap?

2. A user posts a comment and then reloads the page but cannot see it. Which guarantee is missing?

3. Which system gives linearizable writes through consensus?

4. Why is consistency level ALL rarely used for writes in a 3-replica cluster?

Saved on this device. Create a free account to keep it on every device.

Practise this with Sam

A real mock interview, out loud, with an honest scorecard. Free to start.

Start free