What it is
CAP says that during a network partition, a distributed system must choose between consistency (every read sees the latest write) and availability (every request gets a non-error answer). Networks fail, so partition tolerance is not a choice — the real decision is CP versus AP, made per feature, not per system. PACELC extends it to the 99.9% of the time the network is healthy: if Partition, choose A or C; Else, choose Latency or Consistency. That second half matters more day-to-day, because partitions are rare but the latency-versus-consistency trade is paid on every single write.
In an interview this is the framing device for non-functional requirements. The interviewer wants to hear me map the domain: money movement, seat inventory, unique usernames and permissions get strong consistency; likes, view counts, feeds and profile edits go eventual. Defaulting to availability unless the domain demands otherwise — and saying so — is the expected move.
I choose per feature, not per system: checkout and inventory are CP, browsing and feeds are AP — and since partitions are rare, the PACELC question of latency versus consistency is the one I'm actually paying for every day.
The picture
The variants and when to pick each
CP — refuse rather than lie
A CP system stops answering rather than answer wrong. Single-leader databases with synchronous replication, and consensus systems like ZooKeeper and etcd, behave this way: under Raft, the minority side of a partition simply refuses requests. Spanner is the famous refinement — technically CP, but engineered to five nines so the A it sacrifices is almost never visible.
I reach for CP where a stale or conflicting answer is a business incident: double-selling a seat, double-spending a balance, two users claiming one username.
AP — answer, possibly stale
An AP system keeps serving on both sides of a partition and reconciles afterwards. Cassandra, DynamoDB in its default eventually-consistent mode, Riak and DNS all take this bet: the value of an answer now beats the risk of it being seconds old.
This is the right default for read-heavy consumer features. Nobody files a ticket because a like count was stale for 800 ms, and healthy systems converge in well under a second.
PACELC — the version that matters when nothing is broken
Classifying systems the PACELC way is the fluency signal: DynamoDB and Cassandra are PA/EL — available under partition, latency-first in normal operation. MongoDB is commonly cited PA/EC. Spanner, BigTable and HBase are PC/EC — consistency both times, which is exactly why cross-region writes on them are slow.
The practical reading: even with a perfect network, I still choose between fast writes and consistent reads on every operation. That is the trade I should be defending in the interview, not the once-a-year partition.
The nuances that separate levels
Three things worth saying explicitly. First, the C in CAP is linearizability, not the C in ACID — conflating them is a common tell. Second, CAP applies per operation on a single object, not to a whole product — one system can be CP for checkout and AP for browsing, and the best answers mix deliberately. Third, "pick two of three" is a misleading slogan: partition tolerance is mandatory, so you pick one of two, and only while partitioned.
Numbers worth memorising
| Cross-region sync coordination | ~30–150 ms per write — why PC/EC is slow globally |
| Same-region consensus round trip | ~1–5 ms to a majority |
| Eventual-consistency convergence | typically <1 s in a healthy system |
| Spanner TrueTime uncertainty | ~1–7 ms, waited out on commit |
| PACELC to quote | DynamoDB/Cassandra = PA/EL · Spanner/HBase = PC/EC |
Where the interviewer pushes
The push is always to make it concrete: "what does your system literally do during a partition — error, stale read, or block?" The strong answer walks a specific component: the minority side of my etcd cluster refuses writes, so config changes stall but nothing lies; my Cassandra tier keeps accepting writes on both sides and repairs on heal, so a follower might serve a feed that is a second old. Naming the user-visible behaviour — not the acronym — is what scores.
Second push: "point at one feature in your design that should be CP and one that should be AP." This tests whether I treat CAP as a per-feature dial. In a booking system: the seat hold is CP — I'd rather show an error than sell a seat twice — while browsing listings is AP, served stale from cache without apology. If I've claimed everything needs strong consistency, I've also silently signed up for coordination latency on every write, and a good interviewer will bill me for it.