Loading learning content...
If you were to distill all of distributed systems theory into a single insight, it would be this: when a network partition occurs, you must choose between consistency and availability—you cannot have both.
This isn't a limitation of our current technology or a problem to be solved with clever engineering. It's a mathematical theorem, proven in the year 2002 by Seth Gilbert and Nancy Lynch, formalizing an intuition that distributed systems practitioners had held for decades. The theorem—known as the CAP theorem—stands as one of the most important results in computer science and remains the starting point for every serious discussion of distributed system design.
Understanding this trade-off isn't optional for system designers. It shapes every decision about data storage, replication strategy, failover behavior, and client experience. It determines whether your banking system correctly reflects balances during an outage or whether your social media feed shows posts during a network split.
By the end of this page, you will deeply understand the consistency-availability trade-off, the CAP theorem that formalizes it, and—critically—how to make this trade-off in practice. You'll learn to identify where on the consistency-availability spectrum your system should operate and how to reason about the consequences of that choice.
Before we can reason about the trade-off, we need precise definitions. The words 'consistency' and 'availability' are used loosely in the industry, often with conflicting meanings. In the context of the CAP theorem, they have specific technical definitions.
Consistency (Strong/Linearizability):
In CAP terminology, consistency means linearizability—the strongest form of consistency guarantee. A system is linearizable if:
Less formally: after a write completes, every subsequent read (from any client, from any replica) must see that write or a later write. There's a single, universally agreed-upon order of operations.
The CAP theorem's notion of consistency is very strong—specifically linearizability. Weaker consistency models (eventual consistency, causal consistency, read-your-writes) don't trigger the CAP impossibility result in the same way. This subtlety is often lost in casual CAP discussions.
Availability (in CAP context):
In CAP terminology, availability means:
Critically, CAP availability requires that every non-failed node can respond. If your system requires coordination with a potentially unreachable node before responding, it is not 'available' in the CAP sense during a partition.
Network Partitions:
A network partition occurs when messages between some subset of nodes cannot be delivered. This can happen due to:
Partitions are not hypothetical edge cases. In real-world distributed systems, they happen regularly—sometimes multiple times per day in large deployments.
| Property | Formal Definition | Practical Interpretation |
|---|---|---|
| Consistency (C) | Linearizability—all nodes see the same data at the same time | Reads always return the most recent write |
| Availability (A) | Every non-failing node returns a response for every request | The system never refuses to answer |
| Partition Tolerance (P) | The system continues to operate despite network partitions | The system handles message loss between nodes |
The CAP theorem, first conjectured by Eric Brewer in 2000 and proven by Gilbert and Lynch in 2002, states:
In a distributed system, when a network partition occurs, you must choose between consistency and availability—you cannot guarantee both simultaneously.
Or more precisely: No distributed system can simultaneously provide all three of Consistency, Availability, and Partition Tolerance. Since network partitions are unavoidable in distributed systems, you must choose between C and A when a partition occurs.
The CAP theorem is often described as 'pick 2 of 3,' suggesting you could choose CA (no partition tolerance). This is misleading. In any real distributed system, network partitions WILL occur. You don't get to 'choose' partition tolerance—you must handle it. The real choice is: given a partition, do you sacrifice consistency or availability?
Why CAP is True — An Intuitive Proof:
Imagine the simplest distributed system: two nodes (N1 and N2) that replicate the same data. A client can read from or write to either node.
Scenario: Network Partition Occurs
Now suppose the network between N1 and N2 is partitioned—they cannot communicate with each other.
A client writes value = 5 to N1.
Another client wants to read from N2.
You have only two options:
Option 1: Maintain Consistency (Sacrifice Availability)
Option 2: Maintain Availability (Sacrifice Consistency)
There is no third option. N2 cannot return the value written to N1 because it cannot communicate with N1. It must either refuse to answer (lose availability) or return potentially stale data (lose consistency).
The Partition Decision Point:
The CAP trade-off only manifests during partitions. When the network is healthy, a well-designed system can provide both consistency and availability. The question is: what happens when things go wrong?
This is crucial for system design. You're not choosing between 'a consistent system' and 'an available system.' You're choosing your system's failure mode—how it behaves when the network misbehaves.
CP (Consistent + Partition Tolerant) systems prioritize consistency over availability. When a network partition occurs, these systems will refuse to answer requests rather than return potentially incorrect data.
Characteristics of CP Systems:
How CP Systems Work:
Most CP systems use a quorum mechanism. For a write to succeed, it must be acknowledged by a majority of nodes. For a read to succeed, it must query a majority of nodes and take the latest value.
With a majority quorum, at least one node in any read quorum must have participated in the most recent write quorum. This guarantees that the read sees the latest write.
Example: Write Quorum
| System | Use Case | Partition Behavior |
|---|---|---|
| Apache ZooKeeper | Coordination, configuration, leader election | Minority side becomes read-only or unavailable |
| etcd | Kubernetes state, distributed KV store | Requires majority quorum; minority unreachable |
| Google Spanner | Globally distributed SQL database | Uses TrueTime + Paxos; sacrifices availability for global consistency |
| CockroachDB | Distributed SQL database | Raft consensus; partitioned replicas reject writes |
| Consul (default mode) | Service discovery, health checking | Raft-based; requires quorum |
When to Choose CP:
CP systems are appropriate when:
CP systems fail loudly rather than silently. An error message tells you something is wrong; stale data looks correct and may propagate through your system undetected. For critical data, failing loudly is often safer.
AP (Available + Partition Tolerant) systems prioritize availability over consistency. When a network partition occurs, these systems continue to accept reads and writes, even though different partitions may have divergent views of the data.
Characteristics of AP Systems:
How AP Systems Handle Conflicts:
When both sides of a partition accept writes, the data diverges. When the partition heals, the system must reconcile these conflicts. Common strategies include:
1. Last-Writer-Wins (LWW)
2. Vector Clocks
3. Conflict-Free Replicated Data Types (CRDTs)
4. Application-Level Resolution
| System | Use Case | Conflict Strategy |
|---|---|---|
| Amazon DynamoDB (eventually consistent) | Session state, shopping carts, user preferences | Last-writer-wins or version vectors |
| Apache Cassandra | Time-series data, IoT, high-write workloads | Last-writer-wins by default; tunable |
| Riak | User data, session stores, distributed cache | Vector clocks + siblings; application resolves |
| CouchDB | Offline-first apps, edge sync | MVCC with conflict detection; app resolves |
| Amazon S3 | Object storage | Last-writer-wins; eventual consistency on overwrites |
When to Choose AP:
AP systems are appropriate when:
AP systems push complexity to conflict resolution. 'Eventually consistent' sounds simple, but designing correct conflict resolution is hard. What does 'merge two shopping carts' mean if one user removed an item and another added the same item? The consistency problems don't disappear—they're relocated.
The binary 'CP vs. AP' framing, while useful, oversimplifies reality. Consistency exists on a spectrum, with many intermediate models that offer different trade-offs. Understanding this spectrum is essential for nuanced system design.
The Consistency Hierarchy (Strongest to Weakest):
Practical Implications of Each Level:
| Model | Coordination Required | Latency Impact | Use Case |
|---|---|---|---|
| Linearizability | Full coordination (consensus) | Highest latency | Financial transactions, locks |
| Sequential | Ordering coordination | High latency | Database transactions |
| Causal | Dependency tracking | Moderate latency | Collaborative editing |
| Read-Your-Writes | Session affinity or tokens | Low additional latency | User-facing applications |
| Monotonic Reads | Version tracking | Minimal latency | Caching, CDNs |
| Eventual | None (async replication) | Lowest latency | Analytics, logs, metrics |
Tunable Consistency:
Many modern databases offer tunable consistency—you choose the consistency level per operation based on your needs.
For example, in Cassandra:
ONE: Write/read from one replica (fastest, least consistent)QUORUM: Majority of replicas must respond (balanced)ALL: All replicas must respond (strongest, least available)This allows you to choose strong consistency for critical operations (financial transactions) and weaker consistency for less critical operations (view counts) within the same system.
Don't default to the strongest consistency you can get. Each consistency level has costs. Analyze each operation: What's the cost of stale data? What's the cost of unavailability? Choose the weakest consistency level that meets your requirements—you'll gain performance and availability.
The CAP theorem, while foundational, doesn't tell the complete story. It only describes behavior during partitions—but most of the time, your system isn't partitioned. What trade-offs apply during normal operation?
The PACELC Theorem:
Daniel Abadi proposed PACELC as an extension of CAP:
If there is a Partition (P), choose between Availability (A) and Consistency (C). Else (E), when the system is running normally, choose between Latency (L) and Consistency (C).
PACELC recognizes that the consistency-latency trade-off exists all the time, not just during partitions. Strong consistency requires coordination, and coordination takes time.
| System | During Partition (PA or PC) | Else Normal (EL or EC) | Full PACELC |
|---|---|---|---|
| DynamoDB (default) | PA (available) | EL (low latency) | PA/EL |
| Cassandra (QUORUM) | PA (available) | EC (consistent) | PA/EC |
| MongoDB (default) | PA (available) | EC (consistent) | PA/EC |
| ZooKeeper | PC (consistent) | EC (consistent) | PC/EC |
| CockroachDB | PC (consistent) | EC (consistent) | PC/EC |
| Google Spanner | PC (consistent) | EC (consistent) | PC/EC |
The Latency-Consistency Trade-off (Normal Operation):
Even without partitions:
Strong Consistency Requires Round-Trips: To guarantee linearizability, you typically need to wait for acknowledgments from multiple nodes. This adds latency proportional to network round-trip times.
Leader-Based Systems: Many consistent systems route all writes through a single leader. If the leader is geographically distant, every write pays that latency cost.
Conflict Detection: Even optimistic approaches that check for conflicts at commit time add latency if conflicts require retries.
Eventual Consistency is Nearly Free: Async replication can happen in the background. The client experiences only local write latency.
CAP has been criticized for oversimplification. Real partitions are partial and transient. 'Availability' in CAP is all-or-nothing, but real systems degrade gracefully. Nevertheless, CAP remains the essential starting point for reasoning about distributed system trade-offs. Just don't treat it as the complete picture.
Given all this theory, how do you actually decide between consistency and availability for your system? Here's a practical framework.
Step 1: Characterize Your Data
Different data in your system has different requirements:
| Data Type | Stale Reads Harm | Lost Writes Harm | Recommendation |
|---|---|---|---|
| Financial balances | Severe (overdrafts, fraud) | Severe (lost money) | Strong consistency (CP) |
| Inventory counts | Moderate (overselling) | Moderate (stock errors) | Strong for decrements; eventual for reads |
| User preferences | Low (minor UX issues) | Low (user can re-set) | Eventual consistency (AP) |
| Social media feeds | Very low (stale posts) | Low (user will notice, retry) | Eventual consistency (AP) |
| Session state | Low-moderate (logging issues) | Moderate (user logged out) | Session-local consistency |
| Analytics data | Very low (approximate OK) | Very low (aggregates smooth) | Eventual consistency (AP) |
Step 2: Assess Business Impact
For your specific business, quantify (or at least rank) the costs:
These aren't always easy to quantify, but even rough estimates guide decisions.
Step 3: Consider User Experience
Beyond business metrics, consider how users experience each failure mode:
Generally, users prefer consistent failures (error messages) to inconsistent success (different views of reality).
Theory becomes concrete through examples. Let's examine how major systems make the consistency-availability trade-off.
Case Study 1: Amazon's Shopping Cart (AP)
Amazon famously prioritizes availability. Their philosophy: 'It's better to show a stale shopping cart than to show an error page.'
Dynamo (Amazon's influential distributed key-value store) chose AP:
Key Insight: For e-commerce, an available but slightly stale cart converts better than an error page.
Case Study 2: Banking Systems (CP)
Bank core systems universally choose consistency. Incorrect balance displays lead to:
Banking systems use:
Key Insight: For financial systems, a 'system unavailable' message is vastly preferable to showing an incorrect balance.
Case Study 3: Google Docs (Causal Consistency)
Google Docs takes a nuanced approach:
This is neither pure CP nor AP—it's a carefully designed middle ground that suits collaborative editing.
Key Insight: The 'right' consistency model depends on the application semantics. Collaborative documents need different guarantees than financial ledgers.
Most real systems don't uniformly choose CP or AP. They apply different trade-offs to different parts of the data. Inventory decrements might be CP (prevent overselling) while product descriptions are AP (staleness is tolerable). Design with granularity.
Understanding the trade-off is one thing; implementing it is another. Here are common patterns for each choice.
Patterns for CP (Consistency-Preferring) Systems:
Patterns for AP (Availability-Preferring) Systems:
Both CP and AP implementations have complexity—just in different places. CP complexity is in consensus protocols and failure handling. AP complexity is in conflict resolution and convergence verification. Neither is 'simpler' overall.
We've deeply explored the most foundational trade-off in distributed systems. Let's consolidate the key insights:
What's Next:
With the consistency-availability trade-off deeply understood, we'll explore the next major trade-off pair: Latency vs. Throughput. This trade-off shapes performance optimization decisions at every level of system design, from network protocols to database tuning to application architecture.
You now understand the consistency-availability trade-off at a depth sufficient for senior-level system design discussions. You can articulate CAP, evaluate where on the spectrum your system should operate, and reason about implementation approaches. Next, we'll apply this trade-off thinking to the latency-throughput dimension.