What it is
Consistency models define what readers are promised about the recency and ordering of writes. At the strict end, linearizable reads always reflect the latest acknowledged write, as if there were one copy. At the loose end, eventual consistency only promises replicas converge if writes stop. In between sit the useful middle grounds: causal (a reply never appears before its parent comment), read-your-writes and monotonic reads (your view of time never goes backwards). The moment I replicate or shard, I owe the interviewer an answer on this spectrum.
The scoring is per operation, not per system: I pick the cheapest model each read path can tolerate and pay for strength only where staleness breaks correctness. "Timeline reads are eventual; username registration is linearizable via a conditional write" is the shape of a strong answer — and quorums are the standard machinery for buying tunable strength in leaderless stores.
I'd run N=3 with W=2 and R=2 so read and write sets always overlap, then relax specific read paths to eventual — naming which ones, and what staleness they can tolerate.
The picture
The variants and when to pick each
Quorums — R + W > N is the whole trick
Dynamo-style stores keep N replicas per key, acknowledge writes after W of them confirm, and answer reads after querying R. If R + W > N, every read set overlaps every write set, so at least one replica in my read has the latest write — strong-ish consistency without a leader. The canonical config is N=3, W=2, R=2.
The dials are the point: W=1 gives fast, riskier writes; R=1 gives fast reads with staleness; W=N gives maximum durability but any dead node blocks writes. Saying which dial I'd turn for which workload is what demonstrates understanding.
Conflict handling — someone has to merge
With no leader, two writes can land on different replicas concurrently and both get accepted. Last-write-wins (Cassandra's default) picks the later timestamp and silently drops the loser — simple, and quietly lossy. Vector clocks detect the concurrency and hand both versions back for the application to merge — the Dynamo shopping-cart move. CRDTs make the merge automatic for data types that commute, like counters and sets.
Repair machinery keeps replicas converging: read repair fixes stale copies at read time, hinted handoff parks writes for a down node, and anti-entropy with Merkle trees diffs replicas in the background.
Session guarantees — the anomaly users notice
The classic bug: a user posts a comment, the page refreshes from a lagging replica, and their comment has vanished. Read-your-writes fixes it by routing that user's reads to the leader, or to any replica that has caught up to their last write's log position (LSN). Monotonic reads pins a user to one replica so their timeline never jumps backwards. These are cheap, targeted guarantees — strong consistency for one user's session without paying for it globally.
Strong consistency — when only linearizable will do
For the operations that genuinely cannot tolerate staleness — unique username claims, seat inventory, balance movements — I use a single leader with synchronous replication, or consensus (Raft/Paxos) for linearizable reads and writes. A linearizable operation costs roughly one round trip to a majority: 1–5 ms in-region, 30–150 ms across regions, which is exactly why I ring-fence it to the few operations that need it.
Numbers worth memorising
| Canonical quorum | N=3, W=2, R=2 — R + W > N |
| DynamoDB strongly-consistent read | 2× the cost of eventual (1 RCU vs 0.5 per 4 KB), and not served from GSIs |
| Async replication lag (your staleness bound) | usually <1 s when healthy |
| Linearizable op via Raft | ~1 RTT to majority: 1–5 ms in-region, 30–150 ms cross-region |
Where the interviewer pushes
The favourite push is degrading the quorum: "N=3, W=1, R=1 — what can users see?" The strong answer enumerates the anomalies: a write acked by one node can be lost forever if that node dies before replicating; reads can return data missing the last several writes; and a user may not see their own write since R=1 can hit a replica the write never reached. Then the recovery: R + W > N restores the overlap, or session guarantees patch the own-writes case specifically.
Second push: "how does a user see their own comment immediately without sending all reads to the leader?" The answer is session consistency, mechanically: after a write, hand the client its LSN (or timestamp); route that user's next reads to any replica caught up to that LSN, falling back to the leader only when none is. Alternatives worth naming: pin the user to the leader for a few seconds after writing, or serve their own recent writes from a client-side or edge cache. All three keep the global read path cheap.