CAP Theorem Explained: Consistency vs Availability
The CAP theorem explains a limit that appears whenever an application stores or coordinates data across multiple machines: during a network partition, a system cannot guarantee both a single consistent view and uninterrupted availability. This guide is for developers, architects, database engineers, and SREs who need to turn that idea into design decisions. It separates CAP from common oversimplifications, shows what a partition looks like, and connects the theory to replication, quorum systems, and production databases.
What Is the CAP Theorem?
The CAP theorem is a statement about distributed data systems and three properties:
- Consistency: Every successful read receives the latest value, or an error. This is the “single, up-to-date view” meaning of consistency used by CAP.
- Availability: Every request to a non-failed node receives a non-error response, even if that response may not contain the newest value.
- Partition tolerance: The system continues operating despite messages being lost or delayed between groups of nodes.
The theorem says that when a partition occurs, a system must choose between consistency and availability. Partition tolerance is not normally an optional feature in a networked system: a broken switch, overloaded link, firewall rule, or cloud-zone outage can prevent healthy nodes from communicating. The practical decision is therefore usually CP—preserve consistency and reject some requests—or AP—preserve responses and accept stale or conflicting state.
The original formulation is associated with Eric Brewer’s CAP theorem keynote paper. CAP describes behavior during a partition, not a permanent ranking in which a database is always “two out of three.”
Why the CAP Theorem Exists
In a single process, a write and a read can often be ordered by one memory or database transaction. Replication changes that assumption. A client may write value blue to node A while another client reads node B. If the nodes cannot exchange messages, node B cannot know whether its old value is still authoritative.
There are only a few safe responses:
- Node B can reject the read or write until it can confirm the current state. This protects consistency but reduces availability.
- Node B can answer using its local state or accept a local write. This protects availability but permits a stale response or a conflict.
- The system can make a weaker guarantee explicit, such as returning a value only when it is within a bounded staleness window.
This is not a choice caused only by databases. Distributed locks, leader election, inventory counters, configuration stores, and payment workflows face the same uncertainty. A timeout does not prove that a remote node is dead or that a write failed; it proves only that a response did not arrive before the deadline.
For a practical treatment of partial failure and partitions, see the site’s guide to distributed system failures. CAP provides the constraint; failure handling defines what an individual product does about it.
How CAP Works During a Network Partition
Imagine three replicas storing the number of seats remaining for an event. Under normal conditions, all replicas exchange updates. A client sends a request to reserve the final seat, but a partition isolates one replica from the other two.
If the isolated replica continues accepting reservations, two clients may each receive a successful response. When connectivity returns, the replicas must reconcile an overbooked inventory. The system stayed available to the isolated client, but it did not preserve a single consistent value.
If the isolated replica refuses the reservation because it cannot contact a quorum, the system avoids the double booking. Requests routed to that replica fail or wait, so the system sacrifices availability for that operation.
| Property or decision | What it guarantees | Typical partition behavior | Cost |
|---|---|---|---|
| Consistency | Reads observe one authoritative, current history | Require a leader or quorum; reject uncertain operations | Errors, latency, or reduced write capacity |
| Availability | Reachable nodes continue returning responses | Serve local data or accept local writes | Stale reads, conflicts, or reconciliation |
| Partition tolerance | Nodes tolerate lost or delayed communication | Continue with a defined degraded mode | Requires explicit recovery and conflict policy |
| Strong read | A read reflects a committed value | Contact an authoritative replica or quorum | More coordination and latency |
| Eventual convergence | Replicas become equal after updates propagate | Accept temporary divergence | Clients must tolerate staleness and merge rules |
With three voting replicas, a majority quorum is normally two. If the partition divides the cluster into groups of two and one, the group of two can safely continue a leader-based write protocol. The minority remains alive but cannot safely commit independent history. With an even number of replicas, a tie can prevent either side from forming a majority; adding a witness or using an odd voting count can make failure behavior easier to reason about.
CAP Consistency Is Not Every Kind of Consistency
One source of confusion is that “consistency” has several meanings. CAP uses a strong, linearizable-style meaning: operations appear to take effect in one order, and a read after a completed write sees that write. Database documentation may instead discuss read-after-write consistency, session consistency, causal consistency, or eventual consistency.
These guarantees form a spectrum rather than a single switch:
- Linearizable reads and writes prioritize a current, globally ordered result.
- Read-after-write consistency ensures a client sees its own successful update, even if other clients see older data.
- Causal consistency preserves relationships such as “reply appears after the message that caused it.”
- Eventual consistency allows temporary divergence but requires replicas to converge if updates stop.
- Bounded staleness permits an older value within a stated time or version limit.
AWS documents the difference between eventually consistent and strongly consistent reads in DynamoDB. Microsoft Azure Cosmos DB also exposes multiple consistency levels, including strong, bounded staleness, session, consistent prefix, and eventual. These choices show why labeling an entire product simply “CP” or “AP” is often too coarse: one service may offer multiple guarantees, and different operations may use different paths.
CP and AP System Designs
CP: Consistency under a partition
A CP design refuses operations that could create an ambiguous history. Common implementations use a leader and quorum:
- A client sends a write to the current leader.
- The leader replicates the write to enough voting members.
- The write is acknowledged only after the quorum confirms it.
- If the leader loses its quorum, it stops accepting commits.
This pattern suits account balances, unique names, distributed locks, cluster membership, and configuration where conflicting values are more dangerous than a temporary error. The application still needs timeouts and retry-safe request identifiers because a client may lose the response after the write is committed.
CP does not mean that a system is never available. It means that availability is conditional on reaching an authoritative group. A five-node cluster can continue committing with three reachable voting members, while a healthy minority of two cannot safely do so.
AP: Availability under a partition
An AP design lets reachable replicas respond even when they cannot coordinate. It may use asynchronous replication, multi-primary writes, version vectors, last-write-wins rules, or application-specific merges. The service stays responsive, but clients must understand that a response can be stale or that concurrent updates can conflict.
This is useful for shopping-cart drafts, social activity feeds, telemetry, presence indicators, and other workloads where temporary divergence is preferable to an outage. AP is not permission to ignore data loss. The system needs a durable conflict policy, reconciliation process, and observability for replication lag.
A system may provide stronger guarantees during normal operation than during a partition. The CAP label describes the behavior at the point where communication failure forces a choice.
Key Components and Design Levers
Replicas and leaders
Replicas hold copies of state. A leader-based design routes writes through one authority, which simplifies ordering but makes leader election and failover important. Multi-leader designs improve locality and write availability but require conflict detection and resolution.
Quorums
A quorum is the minimum set of replicas that must participate in an operation. If read and write quorums overlap, a read can often discover the latest committed write. Quorum math does not automatically solve partitions: the application must define which versions are valid, how membership changes, and what happens when a node returns with stale data.
Timeouts, leases, and fencing
Timeouts help bound waiting but cannot distinguish a crashed node from a slow network. Leases expire authority after a period, while fencing tokens or epochs prevent an old leader from committing after a replacement is elected. A robust design makes stale leaders harmless instead of trusting a liveness check alone.
Conflict resolution
Last-write-wins is simple but can discard a valid concurrent update, and wall-clock timestamps can be unreliable. Version vectors, operation-based merges, and domain-specific rules preserve more information but increase implementation complexity. For money, inventory, or permissions, “merge later” may be unsafe; those operations usually need a serialized authority.
Failure domains
Three replicas on one host or one rack do not provide three independent failure domains. Place replicas across availability zones or physical sites when the failure model requires it, and ensure the network path between them is not a shared dependency. More replicas improve tolerance only when they fail independently.
Real-World Use Cases
CAP trade-offs appear in several familiar systems:
- Payments and account balances: Prefer a CP workflow so two writers cannot spend the same balance. A request may be retried with an idempotency key after an uncertain timeout.
- Product catalog and search: A short period of stale data may be acceptable for reads, while price or stock updates require stronger coordination.
- Distributed configuration: A CP store prevents different services from applying incompatible feature flags or credentials.
- Collaborative editing: An AP-style design can accept concurrent local changes, then merge operations using a conflict-free data type or domain-specific algorithm.
- Metrics and telemetry: Availability and ingestion continuity often matter more than every reader seeing the newest point immediately.
- Service discovery: Stale endpoints can route traffic to unhealthy instances, so leases, health checks, and fencing must complement replication.
The right decision is usually made per data item and operation, not for an entire application. A single product can use strong coordination for orders, session consistency for a user’s dashboard, and eventual consistency for analytics.
A Practical CAP Decision Guide
Start with the invariant, not the database brand:
- Write the failure scenario. Specify which messages can be delayed, which nodes can fail, and whether a whole zone can be isolated.
- Name the unsafe outcome. Is it a duplicate payment, oversold inventory, stale profile, missing metric, or conflicting document?
- Choose the required guarantee. Define freshness, ordering, duplicate behavior, and acceptable error rates in observable terms.
- Select the authority model. Use a quorum and leader for serialized decisions, or allow local writes with versioning and a merge strategy where divergence is acceptable.
- Design the uncertain response. Return an explicit error, a stale value with metadata, or an accepted-but-pending status. Do not turn a timeout into a false “failed” result.
- Test the partition. Use fault injection to block traffic between replicas, delay acknowledgements, restart leaders, and restore connectivity. Verify both safety and recovery.
A small pseudocode sketch for a CP reservation path looks like this:
reserve(item, request_id):
result = idempotency_store.lookup(request_id)
if result exists:
return result
if not leader.has_quorum():
return retryable_error("authority unavailable")
transaction:
if inventory[item] == 0:
result = sold_out
else:
inventory[item] -= 1
result = reserved
idempotency_store.save(request_id, result)
commit_to_quorum()
return result
The important behavior is not the syntax. The operation has one authority, refuses to guess when quorum is unavailable, and records an idempotency key so a lost response can be retried safely.
Common Misconceptions
“CAP means a database permanently gives up one property”
No. Partition tolerance matters when communication is disrupted. During normal operation, a system can provide low latency and strong reads, then reject or degrade selected operations only during a partition.
“Availability means every request must return the newest data”
That combines availability with freshness. CAP availability means a non-failed node returns a non-error response. The response can be stale in an AP design; if the newest value is mandatory, the operation needs a stronger consistency guarantee.
“More replicas eliminate the trade-off”
More replicas can tolerate more independent failures, but they do not let isolated nodes coordinate without communication. Replication improves durability and capacity while making ordering, quorum, and recovery decisions necessary.
“CAP says latency and scalability do not matter”
CAP addresses a specific partition scenario. Latency, throughput, cost, durability, operational complexity, and consistency models still shape the architecture. A system can choose CP behavior and remain impractical if quorum latency is too high.
Related Articles
- Distributed System Failures: Partitions Explained
- Building Resilient Distributed Systems
- Database Replication Patterns
- Database Sharding Strategies
- Microservices Architecture Patterns
Changelog
- Initial publication: canonical explainer for consistency, availability, and partition trade-offs.

