Consistency Models: What Eventually Means
I used to think “eventual consistency” meant “maybe a few milliseconds.” Turns out it can mean seconds, minutes, or even longer.
The lightbulb moment: consistency models aren’t about what data you store. They’re about what guarantees you make when someone reads it.
The Spectrum#
Linearizability (strongest guarantee): After a write completes, all reads see that value. It’s like everyone’s looking at the same whiteboard. Expensive but simple to reason about.
Causal Consistency (middle ground): If operation A could have caused operation B, everyone sees them in that order. Unrelated operations can appear in different orders. Cheaper than linearizability, but you need to track causality.
Eventual Consistency (weakest guarantee): If writes stop, all replicas will eventually converge. But “eventually” has no time bound. Could be milliseconds. Could be an hour.
Why This Matters#
Say you’re building a post editor. User saves a draft, then immediately refreshes the page.
With linearizability: They always see their latest draft. Database guarantees it.
With eventual consistency: They might see the old version. Feels like data loss, even though the system is working as designed.
Quorum Reads: The Middle Ground#
Here’s a practical pattern. You have 3 replicas. Configure:
- Write to 2 replicas before acknowledging (W=2)
- Read from 2 replicas and take the latest (R=2)
Since W + R > N (2 + 2 > 3), you’re guaranteed to read your own write. Not full linearizability, but stronger than eventual.
W=2, must write to 2 replicas] W --> R1[Replica 1
✓ Written] W --> R2[Replica 2
✓ Written] W -.-> R3[Replica 3
async later] RD[Read Request
R=2, must read from 2 replicas] RD --> R2 RD --> R3 style W fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style R1 fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style R2 fill:#000000,stroke:#00ff00,stroke-width:3px,color:#fff style R3 fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff style RD fill:#000000,stroke:#00ff00,stroke-width:2px,color:#fff
W+R > N (2+2 > 3) guarantees read overlaps with at least one write replica (R2). You always get the latest value.
The Trade-off#
Stronger consistency costs latency. You’re waiting for multiple nodes to agree. Weaker consistency is fast but confusing to users.
There’s no free lunch. Pick based on what your users can tolerate.
I’m still wrapping my head around causal consistency (events that could affect each other stay ordered). But linearizability vs eventual? That one finally makes sense.
What consistency model does your system use? Do you know?