Consistency Model Selection
A consistency model defines which values a read may return given the history of writes. Stronger models are easier to program against but cost coordination. The framework picks the weakest model that keeps each operation correct.
How it works
Linearizability makes operations appear to take effect instantly in one real-time order, and needs consensus or a single leader. Sequential consistency keeps one order consistent with each client's program order. Causal consistency preserves cause-before-effect. Session guarantees give one client read-your-writes and monotonic reads. Bounded staleness caps how old a read can be. Eventual consistency promises only convergence when writes stop.
Implementation steps
- List operations and the invariants each protects, such as unique usernames, non-negative stock, or visible comments.
- Mark which anomalies are tolerable: stale reads, out-of-order views, lost updates, or write skew.
- Map each operation to a model. Invariants that need a global decision, like uniqueness, need linearizable writes or a single owner.
- Use session guarantees for user-facing reads by routing a user to a replica that has seen their writes, or by passing a version token.
- For eventual stores, add conflict resolution: last-writer-wins only where loss is acceptable, otherwise version vectors or mergeable types.
- Configure the datastore explicitly, including quorum sizes where read quorum plus write quorum exceeds replica count.
- Verify with fault-injection and history-checking tools.
Common pitfalls
- Assuming reads from replicas are as fresh as reads from the primary.
- Using last-writer-wins with clock skew and silently dropping updates.
- Confusing transaction isolation levels with distributed consistency models.
- Applying strong consistency globally and then hitting cross-region latency.
- Never testing behaviour during network partitions.
Metrics to watch
- Replica lag and staleness distribution.
- Read-your-writes violation reports.
- Conflict and merge rates.
- Cross-region write latency for strongly consistent operations.
- Availability during partition or failover drills.
Example configuration
operations:
- name: reserve-username
model: linearizable
reason: "uniqueness invariant"
- name: view-own-profile
model: read-your-writes
mechanism: version-token
- name: product-catalog-browse
model: bounded-staleness
maxStalenessSeconds: 30
- name: page-view-counter
model: eventual
conflict: commutative-merge
Practical rollout
Capture the result as a short table in each service's design document listing operations, chosen model, and the anomaly that was accepted. Reviewing that table during incidents quickly shows whether behaviour was a bug or a documented trade-off. Where possible, run a history checker or fault-injection test against staging, since replication settings, failover behaviour, and client libraries frequently weaken guarantees without any visible warning.
Key takeaways
- Start from invariants, then choose the cheapest model that protects them.
- Distinguish isolation levels from distributed consistency.
- Be explicit about conflict resolution in eventual stores.
- Test the guarantees, since vendor labels are not proof.