Every database comparison eventually reaches for the same triangle. Consistency, Availability, Partition tolerance — pick two. It looks clean, it fits on a slide, and it is wrong in the way that quietly costs you an outage.
The CAP theorem is real and it is useful. But the “pick two of three” version has misled a generation of system design interviews. Partitions are not a property you opt into. They are what the network does to you on a Tuesday afternoon. Once you see that, CAP stops being a party trick and becomes an actual tool for choosing where your data lives.

This is the honest version: what the three letters really mean, the one decision CAP forces, and how to turn it into a database choice you can defend.
Three Words That Don’t Mean What You Think
Before the trade-off, the definitions — because most CAP arguments are really vocabulary arguments.
- Consistency here is linearizability: every read returns the most recent write, as if there were a single copy of the data. This is not the “C” in ACID. Same letter, different universe.
- Availability means every request to a non-failing node gets a (non-error) response. Not “fast,” not “usually up” — an actual answer, every time.
- Partition tolerance means the system keeps operating even when the network drops or delays messages between nodes.
Read those again and the myth falls apart on its own. A distributed database runs across a network. Networks partition — a switch dies, a cable is cut, a cloud AZ goes dark. You do not get to not tolerate that. P is not on the menu.
The Only Choice CAP Actually Forces
So if partition tolerance is mandatory, what is the theorem really about? A single, sharp moment.
When a partition splits your cluster into two groups that can’t talk, each side faces a question about a piece of data it can’t fully verify:
- Stay consistent (CP): refuse to answer unless you’re sure you have the latest state. The minority side rejects writes, maybe rejects reads, and waits for the network to heal. Correct, but temporarily unavailable.
- Stay available (AP): answer anyway, from whatever this replica knows, and reconcile the divergence later. Always responsive, but possibly serving stale data.
That is the whole theorem. Not “two of three” — C or A, and only while a partition lasts. When the network is healthy, you happily have both. CAP describes the behaviour of a system under a fault, not its permanent personality.

A bank moving money picks CP: a double-spend is worse than an error message. A social feed picks AP: a slightly stale like count is invisible; a spinner is not.
The Part CAP Leaves Out: The Other 99% of the Time
Here is the trap that “pick two” hides completely. Partitions are rare. A well-run cluster spends the overwhelming majority of its life fully connected. CAP says nothing about that time — and that time is where you actually live.
This is why PACELC matters. It extends CAP to the normal case:
If there is a Partition, choose Availability or Consistency — Else (L), when everything is healthy, choose Latency or Consistency.
That second clause is the decision you make on every request. Strong consistency isn’t free even when the network is perfect: confirming that a read reflects the latest write means coordinating across replicas, and coordination costs milliseconds. Loosen consistency and reads get faster; tighten it and they get slower but truer.
So the real, daily trade-off is not the dramatic outage scenario. It is: how much latency will you pay, on the happy path, to be certain your data is current? That question fires millions of times a day. The partition question fires once a quarter.
It’s Per-Operation, Not Per-Database
The other thing the triangle gets wrong: consistency and availability are not fixed traits stamped on a database. They are choices you make per operation.
Most modern distributed stores expose this directly through quorums. With N replicas, a read waits for R responses and a write for W acknowledgements. Set R + W > N and any read is guaranteed to see the latest committed write — strong consistency, higher latency. Set them lower and you trade freshness for speed.
-- Cassandra: choose the trade-off per statement.-- Strong: read and write quorums overlap (R + W > N).CONSISTENCY QUORUM;INSERT INTO ledger (acct, delta) VALUES ('A42', -100);
-- Fast and available: answer from the nearest replica, accept staleness.CONSISTENCY ONE;SELECT likes FROM post WHERE id = 'p_9f3';The same cluster is CP for the ledger write and AP for the like count. You are not choosing a database’s philosophy; you are choosing the guarantee this specific request needs. DynamoDB has its ConsistentRead flag, Cosmos DB ships five consistency levels, MongoDB has read/write concerns. The label on the box is a default, not a destiny.
So Where Do the Databases Actually Land?
Defaults still matter, because they are what you get before you tune anything. Roughly:
- Lean CP — Google Spanner, HBase, etcd, ZooKeeper, MongoDB (default majority). They will reject or block during a partition to protect correctness. Spanner is the interesting one: it’s CP by design but spends enormous engineering — TrueTime, redundant private networking — to make partitions so rare that it feels highly available.
- Lean AP — Cassandra, DynamoDB, Riak, CouchDB. They keep answering during a split and reconcile afterward with mechanisms like last-write-wins or CRDTs.

And the myth to bury: there is no useful “CA” database. “CA” only describes a single node with no network to partition — a lone Postgres instance. The instant you replicate or shard it, Postgres faces the exact same CP-versus-AP choice as everything else. If a design doc calls something “CA,” someone is reading the triangle, not the system.
How to Actually Choose
Skip the triangle. Ask three questions in order.
- What is the invariant that must never break? If two users can spend the same balance, or two orders can claim the last unit of stock, you need CP on that path. Correctness first; a rejected request is recoverable, a corrupted invariant often is not.
- What can tolerate being slightly stale? Carts, feeds, view counts, recommendations, sessions, telemetry — a few seconds behind is invisible to users and worth the availability and speed. That’s AP, and it’s most of your traffic.
- What latency can the happy path afford? This is the PACELC question. If a read must be strongly consistent and p99 under 10ms, you’re asking for coordination on a deadline — budget for it, or relax one of the two.
Then design the partition explicitly instead of hoping it never comes. Make writes idempotent so a retry after a heal is safe. Use fencing tokens so a stale leader can’t act. Put money and identity behind quorum reads; let the feed serve from the nearest replica. Same cluster, different guarantees, chosen on purpose.
Choosing the store is one decision; keeping the traffic to it sane is another. For the messaging side of a resilient system, see Pub/Sub or Eventarc? Event-Driven GCP Without the Spaghetti and Send 1,000,000 Notifications Without Falling Over.
The Field Rule
The CAP theorem is not a triangle you pick two corners of. Partitions are guaranteed, so partition tolerance is fixed. The real choice is one moment — during a split, do you block to stay correct (CP) or answer to stay available (AP)? — and PACELC handles the other 99% of the time, where you trade latency for consistency on every request. Decide it per operation, not per database: protect the invariants that can’t break, relax everything that can tolerate a little staleness, and design the partition on purpose. Do that and “which database” stops being a religious war and becomes what it should be — a trade-off you made with your eyes open.




From the community
Discussion on the Fediverse
Replies from Mastodon and Bluesky — straight from the open web, no tracking.
Loading replies …
No replies yet. Start the conversation:
Replies could not be loaded right now.