Background
Sections
IntroductionRequirements & Problem AnalysisConstraints & AssumptionsEstimation TechniquesFunctional vs Non-Functional RequirementsMoSCoW PrioritizationSystem Design FundamentalsArchitecture DiagramClass DiagramComponent DiagramData Flow Diagram (DFD)ER Diagram (Entity-Relationship Diagram)High Level Design (HLD)Low Level Design (LLD)Sequence DiagramState DiagramUse Case DiagramData StorageDocument StoresFile StorageGraph DatabasesIn-Memory DatabasesKey-Value StoresNewSQLNoSQL DatabasesObject StorageSQL Databases (RDBMS)Time-Series DatabasesWide-Column StoresDatabase ConceptsACID PropertiesCAP TheoremConsistency ModelsIndexingNormalization & DenormalizationReplicationSharding & PartitioningTransactions & Isolation LevelsScalabilityAuto-Scaling & ElasticityConsensus & Leader ElectionLoad BalancingReplication & Read ReplicasSharding & PartitioningVertical vs Horizontal ScalingAvailability & ReliabilityBackup & Data DurabilityCircuit BreakerData ConsistencyDisaster RecoveryFault Tolerance & FailoverGraceful DegradationHigh AvailabilityNetworkingCDNDNSFirewalls & VPNHTTP & HTTPSLoad Balancer & Reverse ProxyTCP/IP & UDPWebSocketsCachingCache InvalidationCache Read/Write PatternsCaching LayersEviction PoliciesRedis vs MemcachedMessaging & CommunicationDead-Letter QueueIdempotencyKafka vs RabbitMQ vs SQSMessage QueuesPub/SubCompute & ServicesAPI GatewayContainers & OrchestrationMonolith vs MicroservicesServerlessService DiscoveryService MeshWeb Server & App ServerAPI DesignAPI Versioning & IdempotencyAuthentication & AuthorizationGraphQLgRPCPaginationRate Limiting & ThrottlingRESTSecurityAuthentication & AuthorizationData PrivacyEncryptionInput Validation & InjectionOAuth2 & JWTSecrets ManagementXSS & CSRFStorage & File SystemsBackup & RetentionBlock vs File vs Object StorageData Lakes & WarehousesDistributed File SystemsEphemeral StorageObservability & MonitoringDistributed TracingHealth ChecksLoggingMetricsSLI, SLO, SLADesign PatternsBulkhead PatternCircuit Breaker PatternCreational PatternsRate Limiter PatternRetry PatternStructural & Behavioral Patterns

Consistency Models

7 min read

In a Nutshell

CAP gives you a binary choice (CP or AP), but reality is a spectrum. Consistency models describe exactly how fresh a read is relative to the latest write — from strong consistency (every read sees the latest write — simple to reason about, expensive to provide) to eventual consistency (reads might be stale, but the system will eventually converge — cheap, fast, but application must handle staleness). Between these extremes lie several practically useful models that offer specific, weaker guarantees. Choosing the right model is about matching the consistency guarantee to the business requirement, not always picking the strongest one.

2D minimalistic horizontal spectrum bar showing consistency models from left (weakest) to right (strongest): Eventual → Causal → Read-Your-Writes → Monotonic Reads → Strong (Linearizable), with cost/latency increasing from left to right

How It Actually Works

The Consistency Spectrum

Model Guarantee Example Use Case
Strong (Linearizable) Every read sees the latest write, globally ordered After writing balance = $50, any reader anywhere immediately sees $50 Payments, inventory, leader election
Sequential All operations appear in some total order consistent with each client's order Writes appear in the same order to all observers Distributed logs, event sourcing
Causal If operation A caused operation B, everyone sees A before B If Alice posts and Bob replies, everyone sees Alice's post before Bob's reply Social media, messaging
Read-Your-Writes A client always sees its own writes After updating your profile, you immediately see the change User-facing write-then-read flows
Monotonic Reads A client never sees data move backward If you read version 5, you'll never see version 4 on a subsequent read Dashboards, feeds
Eventual If no new writes occur, all replicas will eventually converge DNS propagation — a new record takes minutes/hours to reach all servers DNS, CDN caches, analytics

Strong Consistency (Linearizability)

The strongest guarantee: operations appear to happen instantaneously at some point between their start and end time. Every client sees the same, totally ordered sequence of operations.

Timeline:
Writer: SET x = 1  ─────────▶ (commit at T1)
Reader A:                          GET x → 1 ✓ (always sees latest)
Reader B:                          GET x → 1 ✓ (even from different node)

How to achieve: Consensus protocols (Raft, Paxos) or single-leader with synchronous replication. Expensive — every write requires a majority acknowledgment.

Used by: Google Spanner, CockroachDB, etcd, ZooKeeper.

Eventual Consistency

The weakest useful guarantee: if you stop writing, all replicas will eventually converge to the same value. But "eventually" is undefined — it could be milliseconds or minutes.

Timeline:
Writer: SET x = 1  ─────────▶ (commit at T1)
Reader (same region):              GET x → 1 ✓ (fast — local replica)
Reader (different region):         GET x → 0 ✗ (stale! not yet replicated)
    ... time passes ...            GET x → 1 ✓ (converged)

The problem: What happens between the write and convergence? The application sees stale data. For a social media like count, this is fine. For a bank balance, it's catastrophic.

Used by: Cassandra (default), DynamoDB (default), DNS, CDN caches.

Causal Consistency

Stronger than eventual, weaker than strong. Guarantees that causally related operations are seen in order by all observers, but concurrent (unrelated) operations may be seen in different orders.

Alice posts: "Anyone free for lunch?"       (operation A)
Bob replies: "I am!"                         (operation B, caused by A)

Causal guarantee: Everyone sees A before B.
Without causality: Some users might see B before A ("I am!" without context).

Used by: MongoDB (since 3.6 with causal sessions), some collaborative editing systems.

Read-Your-Writes

After a client writes data, that same client is guaranteed to see its own write on subsequent reads — even if the write hasn't replicated everywhere yet.

User updates profile name → immediately sees the new name
Other users might see the old name for a few seconds → eventually converges

How to implement: Route reads after a write to the same replica that handled the write, or use sticky sessions. Alternatively, track a "last write timestamp" and wait for the replica to catch up.

2D minimalistic diagram showing a user writing to Node A, then reading from Node B (which hasn't replicated yet) and seeing stale data — contrasted with read-your-writes where the user's read is routed back to Node A

Seeing It in Action

Scenario: Consistency model choices for different parts of a social media platform

Feature Consistency Model Why
Account balance (ad credits) Strong (Linearizable) Money cannot be double-spent; every read must reflect the latest debit
Post creation Read-Your-Writes After posting, the author must see their post immediately; others can see it eventually
News feed Eventual A 5-second delay in seeing a friend's post is unnoticeable; availability matters more
Comment threads Causal Replies must appear after the comment they respond to; ordering within a thread matters
Like count Eventual Off-by-a-few is imperceptible; high write throughput matters more than precision
DM read receipts Monotonic Reads Once you see "read," it should never go back to "delivered"

Interview Questions

  1. Q: What's the difference between strong consistency and eventual consistency? When would you choose each? Hint: Strong: every read sees the latest write — use for payments, inventory, authentication. Eventual: reads might be stale but will converge — use for social feeds, analytics, caching. The trade-off is latency and availability: strong consistency requires coordination (consensus), which adds latency and reduces availability during partitions.

  2. Q: A user updates their profile but sees the old name on refresh. What's happening and how do you fix it? Hint: The write went to the primary, but the read hit a replica that hasn't received the update yet (replication lag). Fix with read-your-writes consistency: route the user's reads to the primary after a write, or use a session-level read preference that ensures the replica has caught up (e.g., readPreference: "primaryPreferred" with afterClusterTime).

  3. Q: Explain causal consistency with a messaging example. Hint: Alice sends "Want to grab lunch?" (msg A). Bob replies "Sure, where?" (msg B, causally dependent on A). Causal consistency guarantees every user sees A before B. Without it, a user might see Bob's reply before Alice's question — confusing. Causal consistency tracks dependencies (vector clocks or Lamport timestamps) without the full cost of linearizability.

  4. Q: How does DynamoDB let you choose between eventual and strong consistency? Hint: Per-read setting. ConsistentRead: false (default) reads from any replica — fast but potentially stale. ConsistentRead: true reads from the leader — always current but slower and uses more capacity. Choose per-query based on the operation: strong for account balance, eventual for product listing.

  5. Q: Can you have strong consistency in a multi-region deployment without high latency? Hint: Not easily. Strong consistency requires consensus (majority of replicas agree), and cross-region round trips are 50–200ms. Google Spanner mitigates this with TrueTime (atomic clocks reduce coordination overhead). CockroachDB uses follower reads (read from the closest replica if the data is recent enough). The honest answer: strong consistency across regions always costs latency; the question is how much.

References

Dive Deeper