A theorem stating that a distributed data store can only guarantee two of the three: Consistency, Availability, and Partition Tolerance.
CAP theorem is the 2000 formalization by Eric Brewer of a truth every distributed-systems engineer learns the hard way: when the network partitions (and it will), you can't have both strict consistency and full availability. You have to choose. Every distributed database you use has made this choice explicitly, sometimes surprisingly, and often configurably.
CP databases refuse writes during a partition rather than risk divergence. MongoDB (primary-secondary with majority write concern), HBase, Redis Cluster, etcd, ZooKeeper — all of these will return errors to clients when enough replicas are unreachable. Operationally: queries fail loudly during network issues, but the data you get back is always correct. AP databases accept writes on any available node and reconcile later. Cassandra, DynamoDB, Riak, CouchDB — these keep taking writes during partitions, at the cost of potentially returning stale or divergent data that gets resolved via vector clocks or last-write-wins. Pick based on what your workload tolerates: a fraud-detection system wants CP (wrong answer is worse than no answer); a shopping cart wants AP (better to accept an order and reconcile than to reject during an S3 hiccup).
A fintech client ran their transaction ledger on Cassandra and spent two years fighting consistency anomalies ("why did this transaction appear twice?"). The root cause was always some combination of tuned-too-low consistency levels (QUORUM where they needed ALL), hinted-handoff replaying duplicates, and developers assuming read-your-writes guarantees Cassandra doesn't give you out-of-the-box. Moving the ledger to a CP store (CockroachDB) fixed the class of bugs entirely. Cassandra was the wrong choice for that workload; they'd picked it for "scalability" without understanding the CAP tradeoff. Lesson: CAP isn't an abstract theorem, it's an operational constraint. Read your database's documentation on what happens during a partition before building on it.
The CAP Theorem (also known as Brewer's Theorem) states that any distributed data system can only guarantee two of three properties simultaneously: Consistency, Availability, and Partition Tolerance. Since network partitions are unavoidable in distributed systems, the practical choice is between consistency and availability during a partition.
In practice, network partitions will happen. So the real question is:
| Choice | Behavior During Partition | Example Databases |
|---|---|---|
| CP (Consistent + Partition-tolerant) | Refuses some requests to ensure consistency | MongoDB, HBase, Redis Cluster, etcd |
| AP (Available + Partition-tolerant) | Serves all requests but may return stale data | Cassandra, DynamoDB, CouchDB, Riak |
| CA (Consistent + Available) | Not possible in distributed systems (only single-node like PostgreSQL) | PostgreSQL (single node), MySQL (single node) |
The PACELC theorem extends CAP: even when there is no partition, there is still a tradeoff between Latency and Consistency.
If Partition → choose A or C
Else → choose L (Latency) or C (Consistency)Example: DynamoDB is PA/EL (Available during partitions, Low latency normally). MongoDB is PC/EC (Consistent always, even at higher latency).
CAP pitfalls that trip up practitioners:
ONE, QUORUM, ALL, LOCAL_QUORUM). MongoDB read/write concerns (majority, local, snapshot). Tuning sloppily is the biggest source of "we chose an AP database but wanted consistency" bugs.CAP theorem says a distributed database can guarantee at most two of three properties: Consistency (every read sees the latest write), Availability (every request gets a response), and Partition Tolerance (the system keeps working when the network splits). Since network partitions are inevitable in real systems, you effectively must choose between Consistency and Availability. CP systems refuse requests during partitions to ensure correctness; AP systems serve requests with potentially stale data. The choice shapes how your database behaves when things go wrong.
Kafka is configurable. With `acks=all` plus `min.insync.replicas=2` on a 3-replica topic, Kafka behaves CP — it refuses writes if fewer than 2 in-sync replicas are available, guaranteeing data isn't lost. With `acks=1`, Kafka is more AP — the leader accepts writes without waiting for replicas, at risk of data loss during leader failure. Most Kafka deployments for critical data use `acks=all` + `min.insync.replicas=2`, which is CP for durability purposes. Read your producer/broker settings carefully — the defaults aren't always safe for the workload.
During a network partition, a node receiving a write has two choices: (a) accept the write locally and risk divergence from other nodes that can't see it (sacrifice Consistency), or (b) refuse the write until it can confirm with other nodes (sacrifice Availability). You cannot do both simultaneously — physics. Partition Tolerance isn't really optional in a distributed system because you can't prevent networks from failing. So CAP reduces to a choice between C and A when P is assumed.
Yes, when picking infrastructure components. A metadata catalog needs CP — inconsistent metadata causes wrong query results. An event bus for analytics usually wants AP — better to accept events during partitions than reject them and lose telemetry. A session store depends on use case: auth sessions want CP (stale sessions cause auth bugs), cache sessions can be AP. When evaluating Snowflake vs. DynamoDB vs. Redis vs. Kafka for a pipeline role, CAP classification (plus PACELC) is one of the lenses you use to match the tool to the workload.
PACELC extends CAP: "if Partition, choose Availability or Consistency; Else, choose Latency or Consistency." Even with no partition, there's still a tradeoff between consistency (wait for all replicas to agree) and latency (respond from one replica, maybe stale). DynamoDB is PA/EL — favors availability during partitions and low-latency during normal operation. Google Spanner is PC/EC — favors consistency even during partitions, even at some latency cost. PACELC is more useful than CAP day-to-day because partitions are rare but latency tradeoffs happen constantly.
CP (refuses writes during partition for correctness): MongoDB with majority write concern, HBase, Redis Cluster, ZooKeeper, etcd, CockroachDB, Google Spanner, FoundationDB. AP (accepts writes during partition, reconciles later): Cassandra, DynamoDB (in its default configuration), Riak, CouchDB, Amazon Aurora readers, most DNS systems. Many systems are tunable — Cassandra can be "more CP" with ALL consistency level; DynamoDB has Strong Consistency read mode. Don't memorize the list; read your specific system's docs on partition behavior.
Technically a single-node database can be "CA" because partitions are impossible when there's only one node — there's nothing to partition from. PostgreSQL, MySQL, SQLite on a single instance are commonly described this way. But the moment you add replication, failover, or multi-node deployment, you must make CAP choices. Streaming replication with synchronous commits is more CP; asynchronous replication is more AP. Patroni-managed Postgres clusters make explicit choices about partition behavior. Single-node "CA" is a limit case, not a real distributed property.