Consistency Guarantees Playbook (Linearizability, Serializability, Snapshot Isolation, Session Guarantees)
Date: 2026-02-27
Category: knowledge
Domain: distributed systems / data infrastructure
Why this matters
Teams often ask for “strong consistency” without specifying which guarantee they actually need.
That ambiguity causes expensive mistakes:
- paying latency/availability cost for guarantees the product doesn’t need,
- assuming safety that the database never promised,
- shipping user-visible anomalies (double booking, stale reads, broken counters).
This playbook is a practical map for choosing the minimum sufficient guarantee.
The core distinction most people miss
Two axes are different but frequently conflated:
- Single-operation real-time ordering (e.g., linearizability)
- Multi-operation transaction isolation (e.g., serializability)
You can have one without the other.
Quick definitions (operator-grade)
1) Linearizability (single-object, real-time)
If operation A completes before operation B starts, then B must observe A’s effect.
- Strong single-object guarantee
- Preserves real-time order
- Typically higher coordination cost across replicas
Use when:
- account balance/position must look immediately current after write,
- feature flags or control-plane toggles must be globally current,
- read-after-write correctness is mandatory for the same object.
2) Serializability (transactional, multi-object)
Concurrent transactions must be equivalent to some serial order.
- Protects transaction-level invariants across multiple objects
- Does not require real-time order
- A later transaction in wall-clock time may appear earlier in serialization order
Use when:
- invariant correctness matters more than strict wall-clock ordering,
- you need ACID correctness for multi-row or multi-key updates.
3) Strict serializability (a.k.a. strong/external consistency)
Serializability plus real-time ordering.
Think: transaction-level correctness + linearizability-style real-time constraint.
Use when:
- financial or critical workflows need both invariant safety and intuitive time ordering.
4) Snapshot isolation (SI)
Each transaction reads from a snapshot and commits if no write-write conflict.
- Great concurrency and predictable reads
- Still allows write skew (classic anomaly)
- Not equivalent to full serializability
Use when:
- high throughput and mostly-disjoint writes,
- you can tolerate/model SI anomalies explicitly.
5) Session guarantees (client-centric consistency)
Per-session guarantees such as:
- Read-Your-Writes,
- Monotonic Reads,
- Monotonic Writes,
- Writes-Follow-Reads.
Use when:
- global strong consistency is too expensive,
- but user experience must be coherent for each individual session.
Anomaly checklist (what each level can still allow)
- Read Committed: can still show non-repeatable reads and many race anomalies.
- Snapshot Isolation / Repeatable Read-ish MVCC: can still permit write skew / serialization anomaly.
- Serializable: blocks serialization anomalies, but may not honor real-time order.
- Strict Serializable / External consistency: strongest practical app-level model among these.
Rule of thumb:
If your invariant is “at most one on-call doctor”, SI can fail (write skew).
If your invariant is “every transfer preserves total funds”, serializable+ is usually required.
Product mapping (practical, simplified)
PostgreSQL
- Default is Read Committed.
REPEATABLE READin PostgreSQL is stronger than ANSI minimum in some ways (MVCC snapshot behavior), but serialization anomalies are still possible.SERIALIZABLEis required when you need transaction-order correctness under contention.
Azure Cosmos DB
Offers five levels: Strong, Bounded Staleness, Session, Consistent Prefix, Eventual.
- Strong provides linearizability per Microsoft docs.
- Session is a strong default for user-facing apps needing per-user coherence with better latency/availability tradeoffs.
DynamoDB
- Eventually consistent reads are default.
- Strongly consistent reads are available for base tables and LSIs (not GSIs/streams).
- Global tables are multi-region eventually consistent.
Spanner
- Designed for externally consistent distributed transactions (strict-serializable semantics), enabled by TrueTime uncertainty-aware commit design.
Decision matrix (fast pick)
- Need immediate correctness on a single key/object after write? → Linearizable read path.
- Need multi-row invariant safety? → Serializable.
- Need both multi-object invariants and real-time order intuition? → Strict serializable / external consistency.
- Need scalable UX coherence without global coordination? → Session consistency.
- Need max throughput and can reason about anomalies? → SI/Repeatable Read with explicit safeguards.
Design pattern: layered consistency
Most real systems should not use one consistency mode everywhere.
Pattern:
- Critical write path: Serializable or strict-serializable transaction domain
- User timeline/profile reads: Session guarantees
- Analytics/search/feed: Eventual/consistent-prefix materialized views
- Cross-boundary operations: Outbox + idempotency + reconciliation jobs
This gives correctness where required and speed where affordable.
Verification playbook (before production)
- State invariants explicitly
- e.g., “inventory never negative”, “one active subscription per user”.
- Map each invariant to required guarantee
- don’t select by vendor marketing terms.
- Run concurrency tests with adversarial schedules
- include retry storms, delayed replicas, clock skew, failover.
- Test user semantics, not just DB semantics
- read-your-writes after redirect, mobile reconnect, region failover.
- Monitor anomaly indicators
- unique-constraint retries, invariant-repair job volume, reconciliation drift.
Common failure patterns
- “Strong consistency” hand-waving
- no formal guarantee named in design docs.
- Relying on SI for invariant-heavy workflows
- then discovering write skew in production.
- Ignoring client/session behavior
- backend is correct, UX still appears broken due to stale read path.
- Mixing regions without consistency intent
- accidental cross-region stale reads after writes.
- No explicit compensation/reconciliation loop
- edge anomalies accumulate silently.
One-page policy template
- For money/inventory/booking invariants: Serializable minimum.
- For command/query UX coherence: Session token / read-your-writes enforcement.
- For globally shared control toggles: Linearizable reads or pinned leader read path.
- For analytics: Eventual with freshness SLO (e.g., p95 lag < 60s).
- For each downgrade in consistency, require:
- documented anomalies,
- user-impact analysis,
- mitigation & repair strategy.
References (researched)
- Herlihy & Wing (1990), Linearizability: A Correctness Condition for Concurrent Objects
https://cs.brown.edu/~mph/HerlihyW90/p463-herlihy.pdf - Jepsen consistency models map
https://jepsen.io/consistency/models - Jepsen: Linearizability
https://jepsen.io/consistency/models/linearizable - Jepsen: Strong (Strict) Serializability
https://jepsen.io/consistency/models/strong-serializable - PostgreSQL docs: Transaction isolation
https://www.postgresql.org/docs/current/transaction-iso.html - Berenson et al. (1995), A Critique of ANSI SQL Isolation Levels
https://dl.acm.org/doi/10.1145/223784.223785 - Adya (1999), Weak Consistency: A Generalized Theory and Optimistic Implementations for Distributed Transactions
http://pmg.csail.mit.edu/papers/adya-phd.pdf - Terry et al. (1994), Session Guarantees for Weakly Consistent Replicated Data
https://ieeexplore.ieee.org/document/331722/ - Azure Cosmos DB consistency levels
https://learn.microsoft.com/en-us/azure/cosmos-db/consistency-levels - DynamoDB read consistency
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html - Spanner (OSDI’12) overview page
https://research.google/pubs/spanner-googles-globally-distributed-database-2/