weighing consistency, availability, and partition tolerance
The CAP theorem is often quoted as an abstract formula, but above all it is a practical decision tool for the moment a network actually fails. During a partition, a distributed system has to decide whether it keeps giving consistent answers and sacrifices availability for it, or stays available and accepts temporarily inconsistent data in return.
Table of Contents
- 1. What the CAP theorem actually claims
- 2. Network partitions are the normal case, not the exception
- 3. CP systems: consistency before availability
- 4. AP systems: availability before consistency
- 5. Common misunderstandings about CAP
- 6. PACELC: the extension for latency
- 7. Making CAP decisions in real systems
- 8. Fine grained CAP decisions per operation
- 9. Common database systems placed on the CAP spectrum
- 10. Summary
- 11. FAQ
1. What the CAP theorem actually claims
The CAP theorem, formulated by Eric Brewer and later formally proven by Gilbert and Lynch, states that a distributed system cannot fully guarantee consistency, availability, and partition tolerance at the same time. Consistency here means every read returns the most recently written value, availability means every request receives a response, and partition tolerance means the system keeps functioning despite lost messages between nodes.
A common misinterpretation is treating the CAP theorem as a choice of two out of three properties, as if one could freely pick between CA, CP, and AP. In practice, partition tolerance is not an option but a physical necessity: networks fail, packets get lost, latencies fluctuate unpredictably. A distributed system with more than one node has to accept partition tolerance whether it wants to or not. The real decision forced by the CAP theorem is therefore between consistency and availability, and only during an actual partition, not during normal operation.
This precision matters: outside a partition, a well designed system can very well be both consistent and available. The CAP theorem makes no statement about normal operation, only about behavior during a network disruption. This restriction is often glossed over in simplified presentations of the theorem, but ignoring it in practice leads to fundamentally wrong architecture decisions.
2. Network partitions are the normal case, not the exception
A network partition occurs when nodes of a distributed system are still individually functional but can no longer reach each other. In cloud based environments with multiple data centers or availability zones, such partitions are not rare disaster scenarios but statistically expected events: network components have failure rates, intermediate routing can fail, and even brief latency spikes act like a temporary partition once timeout values are exceeded.
A system designed for the ideal case that treats partitions as an exception often behaves unpredictably in the real incident: some nodes return stale data, others reject requests entirely, a third behavior appears inconsistently between different requests from the same user. Consciously deciding how a system should behave during a partition, before it actually happens, is the real practical benefit of the CAP theorem for architecture decisions.
This decision is not a one time, global attribute of a system, but can and should be made per data type and per operation. An e-commerce system can prioritize availability for product descriptions while prioritizing consistency for payment flows, within the same overall architecture. This granularity is frequently overlooked in simplified discussions of the CAP theorem.
3. CP systems: consistency before availability
A CP system (consistency, partition tolerance) decides during a partition to reject or delay requests rather than return potentially stale data. Classic relational databases with synchronous replication, as well as systems such as etcd or ZooKeeper based on consensus protocols like Raft, follow this pattern: no answer is better than a wrong answer.
The practical advantage lies in predictability: application code built on a CP system can rely on every successful response reflecting the latest state, without needing additional logic to handle stale data. This simplicity on the application side is bought with reduced availability during network disruptions, a clear tradeoff that is often the right choice for configuration data, feature flags, or distributed locks.
CP systems suit data particularly well where a stale answer is more harmful than no answer at all. A distributed lock service that returns incorrect lock information during a partition can lead to simultaneous access to a critical resource, whereas a briefly unreachable lock request merely causes a delay, usually the far more harmless consequence.
-- Example: enforcing CP behavior via synchronous replication (PostgreSQL)
-- Commit waits for acknowledgment from the synchronous replica
ALTER SYSTEM SET synchronous_standby_names = 'replica_1';
ALTER SYSTEM SET synchronous_commit = 'on';
-- During a partition: block writes instead of accepting
-- inconsistent data
BEGIN;
INSERT INTO critical_config (key, value) VALUES ('feature_x', 'enabled');
COMMIT;
-- Commit hangs if the synchronous replica is unreachable,
-- instead of returning immediately with an unacknowledged change
4. AP systems: availability before consistency
An AP system (availability, partition tolerance) answers every request, even during a partition, but accepts that different nodes may temporarily return different answers. Databases such as Cassandra or DynamoDB in their default configuration mode follow this pattern: availability takes priority, conflicts get resolved after the partition through defined mechanisms such as last write wins or vector clocks.
The practical advantage is resilience against network disruptions: an application built on an AP system stays functional for users even when parts of the infrastructure temporarily cannot communicate with each other. This benefit, however, shifts complexity into the application layer: it has to be able to handle potentially conflicting data, for example through conflict resolution logic, or through the conscious decision that minor inconsistencies are acceptable for the given use case.
AP systems suit data well where short lived inconsistency is tolerable and availability carries the higher business value. A shopping cart in an online store, a like counter on social media, or session data are typical examples: a slightly stale display is usually unproblematic, whereas a completely unreachable application means direct revenue loss.
5. Common misunderstandings about CAP
A widespread misunderstanding is treating CA systems, consistency and availability without partition tolerance, as a viable third option. A system without partition tolerance only works as long as no partition occurs, which is unrealistic in practice for any system with more than one node. A classic single node database is technically CA, but it also is not a distributed system in the actual sense to which CAP would even apply.
A second misunderstanding is treating CAP classifications as a static, system wide property. MongoDB, for example, can be configured to lean more strongly CP or more strongly AP depending on read and write concern, within the same installation. Statements like "MongoDB is a CP system" or "Cassandra is an AP system" are rough simplifications that ignore the actual configurability of many modern systems.
A third misunderstanding concerns the time frame: CAP describes behavior during a partition, not a system's general consistency guarantee. A system can be strongly consistent outside partitions and still be classified as AP, because it chooses availability during a partition. This temporal precision is frequently neglected in discussions but leads to significant misunderstandings during system selection.
6. PACELC: the extension for latency
Daniel Abadi extended the CAP theorem with the PACELC model, which closes an important gap: CAP only describes behavior during a partition (P), but says nothing about normal operation. PACELC adds: during a partition (P) you choose between availability (A) and consistency (C), else (E) you choose between latency (L) and consistency (C).
This extension explains why many systems deliberately give up a degree of consistency guarantee even outside a partition: synchronous replication across multiple geographically distributed data centers costs measurable latency on every write, even when no partition is present. A system classified as PA/EL under PACELC chooses availability during a partition and low latency during normal operation, at the cost of strict consistency in both cases.
PACELC thereby makes visible that the CAP decision only describes half of the relevant tradeoffs. An architecture team that considers only CAP overlooks the more daily relevant question: how much latency is an application willing to pay for stronger consistency guarantees during normal operation, a question that arises far more often than an actual network partition.
-- Example: making the PACELC tradeoff visible through read concern choice
-- Strong consistency, higher latency (both DURING and outside a partition)
-- Force reading from primary instead of a potentially stale replica
-- Configuring a read with an explicit consistency requirement
-- (pseudo syntax, as commonly found in many distributed database drivers)
-- Strongly consistent, higher latency:
-- read_preference = 'primary'
-- Low latency, potentially stale data:
-- read_preference = 'nearest_replica'
7. Making CAP decisions in real systems
Practical application of the CAP theorem begins with classifying data by its consistency requirement, not with choosing a database technology. Financial transactions, stock checks before checkout, and permission checks typically belong to data where CP behavior is justified, because a wrong answer has more severe consequences than a delayed or rejected request.
Display data, recommendations, analytics, and most reads in public areas of an application, on the other hand, tolerate AP behavior well: a briefly stale product description or a slightly delayed like counter rarely has a noticeable negative consequence, whereas a completely unreachable application always has one.
A practical approach is to record this classification explicitly in the architecture documentation, instead of implicitly leaving it to whichever database technology happens to be in use. A team that consciously decides which data needs CP behavior and which needs AP behavior makes better technology choices than one that uses a single database technology for all data types and hopes the default configuration fits.
8. Fine grained CAP decisions per operation
Modern distributed databases increasingly allow the CAP decision to be made per individual operation rather than system wide. Cassandra, for example, lets you set the consistency level individually per read or write request, from ONE (fast, weakly consistent) to QUORUM or ALL (slower, more strongly consistent). The same database instance can thus serve different points on the CAP spectrum for different request types.
This fine granularity allows a single application to demand QUORUM consistency for critical writes while non critical reads get by with ONE consistency and correspondingly lower latency. The price for this flexibility is additional complexity in application code, which has to explicitly choose the appropriate consistency requirement for every operation instead of relying on a single, system wide default.
A common mistake is setting the consistency level once at the initial build of the application and never reconsidering it, even though the consistency requirements of individual data types change over the course of product development. Regularly reviewing which operations actually need which consistency guarantee prevents outdated assumptions from creating unnecessarily high latency or unnecessarily high inconsistency risk.
9. Common database systems placed on the CAP spectrum
The table below roughly places common database systems along the CAP spectrum, with the caveat that many systems are configurable and this placement is a simplification.
| System | Default Tendency | Configurability | Typical Use |
|---|---|---|---|
| PostgreSQL (synchronous) | CP | High, via synchronous_commit | Transaction critical business data |
| Cassandra | AP (configurable toward CP) | Very high, per request | Highly available, distributed workloads |
| MongoDB | Configurable, tends toward CP | High, via read/write concern | Mixed workloads |
| etcd, ZooKeeper | CP | Low, consistent by design | Configuration, distributed locks |
| DynamoDB | AP (configurable toward CP) | High, via consistency options | Highly scaled web applications |
| Redis Cluster | AP (by design) | Low, asynchronous replication | Caching, session storage |
| CockroachDB | CP | Medium, via locality configuration | Distributed, strongly consistent SQL workloads |
| Consul | CP | Low, consistent by design | Service discovery, distributed configuration |
This table shows one thing above all: choosing a database system alone does not yet define a CAP strategy. The actual configuration, often different per data type within the same application, determines where a system actually operates on the CAP spectrum, not the general product category.
Mironsoft
Distributed systems and consistency strategy
Not sure how much consistency you really need?
We classify your data by actual consistency needs, configure databases to match CP or AP requirements, and make PACELC tradeoffs visible during normal operation.
Data classification
Define CP and AP requirements explicitly per data type
Configuration review
Set consistency levels and read/write concern correctly
Latency analysis
Measure and optimize PACELC tradeoffs during normal operation
10. Summary
Understanding the CAP theorem in practice means not misreading it as a choice of two out of three properties, but as a forced decision between consistency and availability, exclusively during a network partition. Partition tolerance is not an option but a physical necessity for any system with more than one node. CP systems prioritize correct answers, AP systems prioritize reachability, both with clear, different use cases.
PACELC usefully extends this view to normal operation: the question of latency versus consistency arises far more often than an actual partition and deserves at least as much architectural attention. The most practically important insight is to make CAP decisions per data type, instead of forcing a single strategy across the entire application, because different data have fundamentally different consistency requirements.
Understanding the CAP Theorem in Practice: The Key Points at a Glance
Partition tolerance
Not a choice, but a physical necessity for any system with multiple nodes.
CP vs. AP
The decision only matters during an actual partition, not during normal operation.
PACELC
Extends CAP with latency-consistency tradeoffs, relevant during the far more common normal operation.
Granularity
CAP decisions should be made per data type and operation, not as a blanket system wide rule.