Consistency models define what value a read is allowed to return relative to writes in a distributed system. They matter because every replication, partition-tolerance, and caching decision is also a consistency decision. You think about consistency when selecting storage, designing leader/replica topology, and deciding whether stale reads are acceptable. In interviews, the important skill is mapping each business invariant to the weakest model that still preserves correctness.

Models

Strong or Linearizable

  • Guarantee: reads behave as if operations happen in one real-time order.
  • Read rule: if write W2 completes before read R1 starts, R1 cannot return pre-W2 data.
  • Mechanism: leader-plus-consensus or equivalent linearizable-read protocol (lease/commit-index aware reads).
  • Example: single-leader PostgreSQL for order state.
  • Cost: highest coordination overhead and latency; availability drops during partitions.

Sequential

  • Guarantee: all operations appear in one total order that preserves each client’s program order.
  • Difference from linearizable: order must be globally consistent, but not tied to wall-clock completion time.
  • Mechanism: global serialization logic without strict real-time constraints.
  • Example: shared preference changes where clients must agree on one operation order.
  • Example: ZooKeeper exposes linearizable writes and sequentially consistent reads, so designs often separate write-path correctness from read freshness.
  • Cost: still coordination-heavy, but weaker real-time freshness than linearizable.

Causal

  • Guarantee: causally related operations must be seen in order.
  • Concurrency rule: unrelated concurrent operations can appear in different orders.
  • Mechanism: dependency tracking (for example version vectors or causal metadata).
  • Example: chat replies should not appear before the original message.
  • Example: collaborative edits preserve dependency chains while merging concurrent edits.
  • Cost: lower latency than strict global ordering, but extra dependency metadata.

Eventual

  • Guarantee: if no new writes occur, replicas converge.
  • Mechanism: asynchronous replication plus conflict resolution policy.
  • Example: DNS propagation.
  • Example: Dynamo-style stores and lagging Redis replicas.
  • Cost: cheapest coordination model, but stale reads are expected.
  • Design impact: application code must tolerate temporary divergence.

Read-your-writes or Session

  • Guarantee: a client sees its own successful writes in its session.
  • Mechanism: session token, sticky routing, or dependency-aware replica selection.
  • Example: user edits profile and immediately refreshes profile page.
  • Use case: common middle ground for user-facing flows.
  • Cost: lower than global strong consistency, but requires session propagation discipline.

Session consistency can contain four distinct client-scoped guarantees:

  • Read your writes: after a client writes profile.name = "Ada", its later reads do not return the old name.
  • Monotonic reads: once a client observes version 12, it never later observes version 11.
  • Monotonic writes: a client’s writes are applied in the order the client issued them.
  • Writes follow reads: a write based on a value the client read is ordered after that observed version.

A product may provide only a subset, so name the required guarantee instead of relying on the phrase “session consistency.” Stores commonly return a version or session token after a write. The client sends it with the next request, and a replica may answer only after reaching that causal position; otherwise the request waits, routes to a fresher replica, or fails within its deadline.

For example, a shipping-address update returns token region-a:1842. The checkout read carries that token and cannot use a replica still at region-a:1839, although other users may still see older data. The token must survive load balancing; keeping it only in one web server’s memory breaks the guarantee when the next request reaches another instance.

Eventual consistency mechanisms and user-visible guarantees

“Eventual” states only that replicas converge after writes stop. The mechanism determines what users can observe and how conflicts are repaired.

MechanismWhat convergesRequired failure logicUseful user guarantee
Asynchronous replicaCopies of one record or logDetect lag, choose conflict/version policy, repair missing dataBounded staleness if lag is measured and enforced
Asynchronous projectionRead model derived from an authoritative log/storeIdempotent replay, checkpoints, poison-event handlingShow projection version/freshness; route critical post-write reads to source
Saga workflowSeveral local transactionsPersist workflow state, retry safely, compensate completed stepsExpose Pending, Completed, or Compensating instead of claiming instant completion
CQRSSeparately shaped write and read modelsPublish committed changes reliably and rebuild projectionsRead model can lag while write acknowledgement remains authoritative
Conflict-aware multi-writer replicationConcurrent versions of the same logical dataCausality/version metadata plus deterministic or application mergeNever silently discard a conflicting user edit

Example: an order API commits OrderPlaced in the authoritative store and returns 202 Pending. A projection updates order history asynchronously, while a saga reserves inventory and captures payment. The UI uses read-your-writes against the authoritative order version until the projection catches up. A failed reservation becomes an explicit compensation state; CQRS did not perform the compensation, and messaging alone did not define the consistency guarantee.

Tradeoffs

ModelGuaranteeExample Use CaseCost
Strong / LinearizableLatest write in real-time orderPayments, inventory decrement, distributed lock stateHighest latency, lower availability under partition
SequentialOne global order preserving per-client orderShared config updatesHigh coordination, weaker real-time guarantee
CausalPreserve cause/effect orderChat threads, collaborative docsMedium complexity, dependency metadata
SessionClient sees own writesProfile/settings updatesLow-medium cost, session token plumbing
EventualConverges after writes stopCatalog/cache/reference dataLowest coordination, stale reads expected

Tunable product consistency

Some databases expose several positions in this taxonomy. Azure Cosmos DB offers five consistency levels, each with a different observable promise:

LevelObservable promiseExample
StrongReads return the latest committed versionA globally ordered control record where stale reads are unacceptable
Bounded StalenessReads lag by at most configured versions or timeInventory dashboards with an explicit maximum lag
SessionOne client gets read-your-writes and related session guaranteesShopping profile and cart interactions
Consistent PrefixReads never observe writes out of order, but may lagA public activity feed where order matters more than freshness
EventualReplicas converge without ordering or freshness boundsDerived recommendations or counters tolerant of temporary anomalies

Choose from the operation’s invariant and user experience, not from a product-wide “strong versus eventual” label. The account default constrains the available behavior, while an individual read can be overridden downward when that default permits it. Never silently weaken a read that enforces a business invariant.

The .NET SDK captures session tokens from responses and sends them on later requests made through the same client. Reuse a singleton CosmosClient; creating one per request discards connection pools and makes session behavior harder to preserve. When a session crosses services, explicitly propagate the relevant token only when the API contract owns that guarantee.

Pitfalls

  • Assuming strong when behavior is eventual: stale reads cause duplicate actions, confusing UI, and contradictory confirmations.

    • Cause: implicit read-after-write assumptions in asynchronously replicated paths.
    • Mitigation: explicit freshness contracts, session consistency on critical UX flows, idempotent writes, and version checks.
  • Over-specifying consistency: paying strong-consistency latency for low-value reads.

    • Cause: one-size-fits-all policy across all entities.
    • Mitigation: classify data by invariant criticality; reserve strongest guarantees for correctness-critical aggregates.
  • Mixing levels without boundary rules: one service assumes fresh reads while another serves lagged projections.

    • Cause: architecture docs list storage systems but not consistency contracts.
    • Mitigation: define consistency in API contracts and test with induced replica lag.

Practical decision checklist

  • Define the invariant first: what must never be wrong from a business perspective.
  • Separate write-path correctness from read-path freshness; they are often different requirements.
  • Decide whether read-after-write must hold for everyone or only for the acting user.
  • For each endpoint, set an explicit freshness budget (for example: “up to 2 seconds stale”).
  • Model partition behavior up front: which operations fail closed vs continue degraded.
  • Add observability for replica lag, cache age, and stale-read rate.
  • Use Idempotency keys on writes so retries are safe when consistency is weaker.
  • Test failure modes with delayed replication and partial-region outages.
  • Keep consistency decisions visible in architecture docs and API contracts.

Optimistic write protection

The HTTP conditional-request contract prevents lost updates by requiring If-Match, returning 428 when absent, and enforcing the validator with one atomic compare-and-swap write. An application-side check followed by an unconditional save is still racy.

Questions

References