CAP & PACELC
The CAP theorem is one of the most cited results in distributed systems. It states that any distributed data store can provide at most two of the following three properties: Consistency, Availability, and Partition tolerance. In practice, because networks are unreliable, partition tolerance is not optional — so the real tradeoff is between consistency and availability.
PACELC extends CAP by recognizing that even when there is no partition, there is a tradeoff between Latency and Consistency. Together, CAP and PACELC provide a useful vocabulary for reasoning about distributed database design.
This guide explains the theorem clearly, debunks common misconceptions, and shows how real systems make these tradeoffs every day.
CAP uses three properties with specific technical meanings. It is important not to confuse colloquial usage with the theorem's definitions.
| Property | Meaning | Plain English |
|---|---|---|
| Consistency | Every read receives the most recent write or an error | All nodes agree on the same data |
| Availability | Every request receives a non-error response, without guarantee it contains the most recent write | The system responds, possibly with stale data |
| Partition tolerance | The system continues to operate despite arbitrary message loss or failure of part of the system | The system survives network partitions |
note
A network partition occurs when nodes cannot communicate with each other. Partitions are inevitable: switches fail, packets are dropped, regions lose connectivity, and GC pauses delay heartbeats. A system that is not partition-tolerant would halt whenever the network hiccups, making it unsuitable for real distributed deployments.
| 1 | Network partition scenario: |
| 2 | |
| 3 | ┌───────────┐ X ┌───────────┐ |
| 4 | │ Node A │◄────partition──►│ Node B │ |
| 5 | │ (primary)│ │ (replica)│ |
| 6 | └───────────┘ └───────────┘ |
| 7 | |
| 8 | A client writes to Node A. Node B does not see it. |
| 9 | |
| 10 | Choices: |
| 11 | 1. Wait for B to acknowledge → Consistent but unavailable |
| 12 | 2. Acknowledge immediately → Available but inconsistent |
| 13 | 3. Refuse all writes → Consistent but unavailable |
| 14 | |
| 15 | CAP says you cannot be both consistent and available |
| 16 | while the partition exists. |
best practice
CP systems choose consistency over availability during a partition. They refuse requests or block until the partition heals to avoid serving stale data. AP systems choose availability over consistency during a partition. They continue serving reads and writes, accepting that replicas may diverge temporarily.
| System | Class | Why |
|---|---|---|
| PostgreSQL (single node) | CA | Consistent and available, not distributed |
| etcd / ZooKeeper | CP | Consensus; leader refuses writes without quorum |
| Cassandra | AP tunable | Continues serving; consistency level per query |
| DynamoDB | AP tunable | Eventually consistent by default; strongly consistent reads optional |
| MongoDB (default) | CP | Primary acknowledges writes; reads from primary |
info
PACELC, proposed by Daniel Abadi, extends CAP with the observation that even when there is no partition, there is a tradeoff between Latency and Consistency. The acronym reads: "If there is a Partition, choose Availability or Consistency; Else, choose Latency or Consistency."
| 1 | PACELC breakdown: |
| 2 | |
| 3 | P → Partition |
| 4 | A → Availability |
| 5 | C → Consistency |
| 6 | E → Else (no partition) |
| 7 | L → Latency |
| 8 | C → Consistency |
| 9 | |
| 10 | If Partition: |
| 11 | choose Availability OR Consistency (CAP) |
| 12 | Else (no partition): |
| 13 | choose Latency OR Consistency |
| 14 | |
| 15 | Examples: |
| 16 | - DynamoDB default: PA/EL |
| 17 | Partition → Available; Else → Low latency |
| 18 | - Spanner: PC/EC |
| 19 | Partition → Consistent; Else → Consistent (with TrueTime) |
| 20 | - Cassandra with QUORUM: PA/EC |
| 21 | Partition → Available; Else → Consistent |
note
Consistency is not binary. There is a spectrum from strong to weak, each with different guarantees and costs. Choosing the right model depends on what correctness means for your application.
| Model | Guarantee | Example Use Case |
|---|---|---|
| Strong / Linearizable | Every operation appears to happen atomically at one point in time | Bank account balances |
| Sequential | All operations appear in some total order consistent with real-time | Collaborative editing |
| Causal | causally related operations are seen in order | Messaging, comments |
| Eventual | If no new updates, replicas converge | Social like counts, CDNs |
best practice
The CAP/PACELC framework is most useful when applied to concrete design decisions. Here are common scenarios and the consistency choices that make sense.
| Scenario | Priority | Typical Choice |
|---|---|---|
| Payment processing | Consistency | CP, strongly consistent ledger |
| Product catalog | Availability + latency | AP, cached eventually consistent reads |
| Session store | Latency | AP in-memory replicated cache |
| Inventory reservation | Consistency | CP with optimistic locking |
| Analytics pipeline | Availability + throughput | AP event streaming |
pro tip
Modern distributed databases rarely force a global CP or AP choice. Instead, they expose tunable consistency levels per operation. Understanding these knobs lets you optimize for latency and correctness without changing databases.
| 1 | Cassandra consistency levels: |
| 2 | |
| 3 | ONE: Read/write acknowledged by one replica |
| 4 | Fastest, lowest consistency |
| 5 | |
| 6 | QUORUM: Read/write acknowledged by majority of replicas |
| 7 | Balanced consistency and availability |
| 8 | |
| 9 | ALL: Read/write acknowledged by all replicas |
| 10 | Strongest consistency, lowest availability |
| 11 | |
| 12 | LOCAL_QUORUM: Quorum within the local data center |
| 13 | Avoids cross-DC latency for regional workloads |
| 14 | |
| 15 | EACH_QUORUM: Quorum in every data center |
| 16 | Strong global consistency, higher latency |
| Pattern | Read Consistency | Write Consistency | Result |
|---|---|---|---|
| Max availability | ONE | ONE | Fastest, eventual consistency |
| Balanced | QUORUM | QUORUM | Read-your-writes for most cases |
| Strong | ALL | ALL | Linearizable, fragile |
| Fast local reads, strong writes | LOCAL_ONE | EACH_QUORUM | Durable writes, fast local reads |
warning