Loading...
Loading...
Weak, Eventual, and Strong consistency explained
Last topic gave you the per-operation dial: N equals 3 with W equals 1 for the 1 ms cart add, and R plus W greater than N for the checkout that waits on two confirmations. Now product asks the follow-up nobody prepared you for. A user changes their name, reloads in the next second, and sees the old one. For how long is that okay? A millisecond? A minute? Until they complain? “Eventually consistent,” which only promises convergence if writes pause, is not an answer to that question. The rejected version of this plan is to leave the dial on fast writes everywhere and hope nobody notices: with W equals 1 and R equals 1, the reload can hit a replica that has not caught up, and users notice their own edits first, every time.
Consistency is not one setting. It is a dial from “anything goes” to “everyone agrees instantly,” and each notch has a name, a cost, and a natural habitat. Weak consistency, meaning reads may return anything with no ordering promise, sits at the loose end. Eventual consistency, meaning copies converge once writes pause, sits in the middle. Strong consistency, meaning every read sees the newest write, sits at the strict end. This topic is the dial, walked from loosest to strictest.
Weak consistency means reads may return anything, including nothing useful, with no ordering promise at all. Sounds useless, until you realize a voice call does not need last second's audio. It needs this second's, instantly, or the conversation dies. Dropping an old packet is better than delaying a live one.
Lives in: voice, video, live games, cached guesses. Anywhere a stale answer arriving now beats a perfect answer arriving late.
Eventual consistency means writes spread asynchronously, while stragglers catch up in milliseconds to seconds. The formal promise is modest, because it only requires convergence once writing stops, but in practice “eventually” usually means “before you blink” inside one region, and seconds across continents.
Lives in: DNS lookups, feeds, catalogs, carts. Anywhere a minute-old truth harms no one.
The trick that makes it livable: read-your-writes, meaning a user always sees their own latest edit. Route a user's own fresh edits back to the primary copy for a few seconds, and the most visible staleness (“where did my post go?”) vanishes while everything else stays fast.
Strong consistency means a write is not done until enough copies confirm it, so every later read sees it, everywhere, guaranteed. Ledgers, seat maps, inventory counts live here, anywhere “close enough” is a lawsuit. The mechanism is waiting: the write holds the response until a quorum, meaning a majority of copies, has it on disk.
Lives in: single-node Postgres, which gives this for free because there is only one copy, and global stores like Spanner, Google's worldwide database, that pay coordination on every write. The price is latency on every write and fragility when copies cannot be reached.
| Notch | Speed | Uptime | Truth |
|---|---|---|---|
| Weak | Fastest | Always up | No promises |
| Eventual | Fast | Always up | Right shortly |
| Strong | Waits on copies | Dips in storms | Right now |
Weak, eventual, strong is the tourist map. Working systems live in the middle notches, which are guarantees named after the specific confusion they prevent. A user who edits their name, reloads, and sees the old one did not hit “eventual.” They hit missing read-your-writes. A feed that shows a reply before the post it answers broke causal consistency, meaning causes must appear before their effects. Learn these three and most “stale data” stories snap into focus.
Read-your-writes means you always see your own latest edit, usually built by pinning your session to the primary copy for a few seconds after a write, or by attaching a version token, meaning a small stamp the client sends back so the server knows how fresh the client already is. Monotonic reads means time never runs backward for one session: once you have seen version 7, no replica may show you version 6 again, usually enforced by remembering the highest version each client saw and refusing older ones. Both are cheap, both kill the most visible staleness, and both should come before reaching for strong consistency, because they fix the complaints users actually file.
If one user posts and another replies, nobody should see the reply first. That ordering, with causes before effects, is causal consistency. The mechanism is dependency tracking: replicas carry metadata about which writes each write depends on, often implemented with vector clocks, which are per-replica counters that let servers compare “happened before” without synchronized wall clocks. It costs more than plain eventual because every write drags its history along, but feeds, comments, and chat need it. Without it, moderation deletes arrive after the content they deleted, and users screenshot the gap.
Bounded staleness means some stores let you put a number on eventually: reads lag writes by at most K versions or T seconds, or the read fails over to a fresher replica. The mechanism is a freshness check, where the replica compares its version against the bound and forwards the read to the primary when it is too far behind. That bound is the knob product actually wants (“my edit is visible everywhere within two seconds”), and it is what lets teams promise a deadline instead of a shrug.
Eventual consistency breaks in two beloved ways. First, the disappearing post: the write lands on replica A, the user's next read hits replica B, and their own content is gone for a second or two. To users that reads as data loss, and they hit “post” again, so now you have duplicates. Second, the double effect: two replicas both accept a non-idempotent action, meaning an action like charging or decrementing that must run exactly once, and the merge runs it twice. Likes survive doubling. Payments do not, and the duplicate charge is the edge case that pages billing teams.
The dial is not theory. It is product decisions you already use. Carts on DynamoDB, Amazon's hosted key-value store, stay writable during storms and reconcile later, because refusing a cart costs more than merging one. Inbox and feed stores in the Cassandra style make the same call: a message visible seconds late harms nobody. On the other end, Postgres gives single-node strong consistency for free, because one copy cannot disagree with itself, which is why money starts there, and Spanner, Google's global database, sells global strong consistency for teams willing to pay its coordination price on every write.
Even object storage moved along the dial: S3, Amazon's hosted blob storage, famously offered only eventual consistency on overwrites for years, then upgraded to strong read-after-write in 2020, with the same API and a stricter notch, because the industry kept tripping over the old one when a fresh upload read back as missing. When in doubt, ask which mistake costs more: showing something slightly old, or showing nothing at all? Retries only fix idempotent work, meaning work safe to repeat, so pair them with keys. Retrying a charge without one creates the duplicate you were trying to avoid.
The dial is set: sticky reads for 2 to 5 seconds kill the disappearing post, idempotency keys collapse the duplicate charge, and last-writer-wins stays far away from money. But dials do not turn themselves. When a server dies at 2am, three jobs start: notice the death, decide who leads next without crowning two leaders, and take over without resurrecting the old one. What machinery runs those three jobs?