Part 4 · Databases & Data at Scale

CAP Theorem & PACELC Without the Confusion

“MongoDB is CP, Cassandra is AP, pick two of three” — mostly misleading. What CAP really says about network partitions, why “CA” isn't a real option, and PACELC: the latency-vs-consistency trade you pay every day, even when nothing is broken.

Lesson 2710 min readintermediate#cap#distributed-systems

On this page

  1. The Problem
  2. The Core Idea
  3. How It Works
  4. Trade-offs
  5. In the Real World
  6. Interview Questions
  7. Key Takeaways
  8. Further Reading

The Problem

Sooner or later, every system-design talk reaches the CAP theorem. A theorem is a rule that has been proved. You will hear lines like these:

  • "MongoDB is CP."
  • "Cassandra is AP."
  • "You can only pick two out of three!"

People repeat these lines, but most cannot explain what they mean. Many of the lines are misleading or wrong.

If you understand CAP well, you can answer a real design question: when the network between my servers breaks, what should my system do? Should it refuse requests, or risk giving out-of-date answers? PACELC (a longer version of CAP) adds a question that matters every single day, even when nothing is broken.

The Core Idea

Imagine a bank with two branches, Mumbai and Delhi. They share account balances by phone. One day the phone line between them goes dead. You walk into the Delhi branch to withdraw ₹10,000.

The Delhi branch has two choices:

  1. Refuse (or make you wait): "Sorry, we cannot confirm your latest balance with Mumbai right now." This keeps the data consistent. Nobody can overdraw by withdrawing in both cities. But the branch is not available to you.
  2. Allow it, based on Delhi's last known balance. The branch stays available. But the balance might be wrong, because maybe you just withdrew in Mumbai too. The two branches now disagree.

There is no third option that gives you both, while the line is down. That is the CAP theorem. The three letters stand for Consistency, Availability and Partition tolerance.

How It Works

The three letters, precisely

C: Consistency (in CAP, this means linearizability). Every read sees the most recent write, as if there were only one copy of the data. Once anyone sees a new value, nobody sees the old value afterwards. (Linearizability is the strict name for this behaviour.)

⚠️ This is not the "C" in ACID (Lesson 21). It is the same word with a different meaning.

A: Availability. Every request to a working (non-failed) node gets a response. It is not an error and not an endless wait. But the data in the response might not be the latest. (A node is one machine in the system.)

P: Partition tolerance. A network partition is a network failure that splits the nodes into groups, and the groups cannot talk to each other. Partition tolerance means the system keeps working even when the network drops or delays messages between nodes.

What CAP actually says

When a network partition happens, a distributed system (a system of many machines that work together) must choose between consistency and availability.

Replica A
₹100
Replica B
₹100
  1. Write once, then cut the network and write on both sides.
Two replicas (copies) of one balance. Write, then cut the network and try writing and reading on both sides. Do it first as a CP system, then as an AP one. · interactive

Why "pick two of three" is misleading

The popular triangle suggests that you can pick CA: consistent and available, but not partition-tolerant. In a real distributed system, you cannot opt out of partitions. Networks will drop packets, switches will fail, cables will be cut, and cloud zones will lose connection to each other. A partition happens to you. It is not a feature that you choose.

So the real choice is:

When a partition happens: C or A?

And when there is no partition, you can have both. CAP says nothing about normal operation. PACELC fills this gap.

(A database with a single node is not a CAP example at all. There is no network between copies that can be split. If that one node dies, the database is simply down.)

CP vs AP behaviour

CP (choose consistency during partitions). Nodes that cannot confirm that they have the latest data refuse requests or return errors until the partition heals. Systems built on consensus (algorithms like Raft and Paxos, where machines vote to agree on one answer) work like this. Only the side with a majority of the nodes can accept writes. The minority side stops.

  • Good for: bank balances, inventory counts, leader election (choosing one boss machine), configuration, locks, and anything where a wrong answer is worse than no answer.
  • Examples of this behaviour: etcd, ZooKeeper, Consul, Google Spanner, and most relational databases with synchronous failover (a standby copy that always has the latest data takes over).

AP (choose availability during partitions). Every node keeps answering, even if its data may be stale, and keeps accepting writes. The copies are made equal again later. This is called eventual consistency (Lesson 28).

  • Good for: shopping carts, social feeds, like counts, product catalogues, DNS, and anything where a slightly old answer is better than an error.
  • Examples of this behaviour: Cassandra and DynamoDB in their default modes, Riak, CouchDB, DNS.

Most real systems are tunable, not simply "CP" or "AP"

  • Cassandra: with consistency level ONE (one replica must answer), it behaves AP-style. With QUORUM reads and writes (a majority of replicas must answer, so W + R > N, see Lesson 24), it behaves much more like CP.
  • DynamoDB: reads are eventually consistent by default (they may return slightly old data). You can ask for strongly consistent reads (and use transactions) when you need them.
  • MongoDB: behaviour depends on its "read concern" and "write concern" settings. These settings say how many nodes must confirm a read or a write. It also depends on which node you read from.
  • PostgreSQL with replicas: reading from the primary is consistent. Reading from an async replica (a copy that is updated later) may return stale data.

That is why Martin Kleppmann argued, in a well-known article, that we should stop labelling databases as simply "CP" or "AP". The real behaviour depends on the settings, on the operation, and on the kind of failure. It is more useful to ask: "For this operation, with these settings, what happens during a partition?"

PACELC: the everyday trade-off

Partitions are fairly rare. But there is a trade-off that you pay all the time. The computer scientist Daniel Abadi described it with the name PACELC:

If there is a Partition (P), choose between Availability (A) and Consistency (C); Else (E), when running normally, choose between Latency (L) and Consistency (C). (Latency is the time one request takes.)

  1. 1
    Is there a network partition right now?
    rare, but it will happen
  2. 2
    Availability or Consistency
    answer with possibly stale data, or refuse and wait
  3. 3
    Latency or Consistency
    answer from the nearest copy now, or coordinate first (extra round trips)
PACELC in one decision tree. · flow

Why is there a latency cost even without failures? To make sure that every read sees the latest write, nodes must coordinate. They wait for replicas to confirm, or they check with a leader or a majority. This needs extra network round trips (a message there and a reply back). Between regions, each round trip can take 50–200 ms (Lesson 10).

  • EL (prefer low latency): answer at once from the nearest copy. The answer might be slightly stale.
  • EC (prefer consistency): wait for the coordination. Every read is up to date, but it is slower.

Classifying some systems with PACELC

Each label has two parts. The part before the slash is the choice during a Partition (PA or PC). The part after the slash is the choice Else, in normal operation (EL or EC). These labels are rough and depend on the settings:

System (typical config)During partitionNormal operationLabel
Cassandra / DynamoDB (default)AvailabilityLatencyPA/EL
Google SpannerConsistencyConsistencyPC/EC
Traditional single-primary SQL with sync replicasConsistencyConsistencyPC/EC
MongoDB (common defaults)Consistency (primary only)Mostly latency/consistency depending on read settingsOften described as PC/EC, varies

Again: use these labels as a way to think, not as fixed truths.

CP: keep consistency
  • •Minority side refuses writes or returns errors
  • +Never a wrong or conflicting answer
  • −Some users see “try again later”
Use whenBalances, inventory, bookings, locks, leader election (etcd, ZooKeeper, Spanner)
AP: keep availability
  • •Every node keeps answering and accepting writes
  • +Always responds, stays fast
  • −Stale reads; conflicts to reconcile later
Use whenCarts, feeds, like counts, catalogues, DNS (Cassandra and DynamoDB defaults)
What each choice looks like to a user during a partition. · compare

Using CAP and PACELC in design

Ask these questions for each feature, not for the whole system:

  1. What happens if two users see different values for a few seconds?
    • Like counts, view counts, "last seen", recommendations: this is acceptable. Choose A and L (availability and low latency).
    • Account balance, stock at checkout, seat booking, usernames: this is not acceptable. Choose C (consistency), even if it is slower or sometimes unavailable.
  2. What should the user see during a failure?
    • An error ("please try again")? A read-only mode? Old data with a warning?
  3. How far apart are the copies? In the same zone (coordination is cheap) or on different continents (coordination is expensive)?

Many systems mix both. An e-commerce site can serve product pages from AP-style caches and replicas (fast, but maybe slightly stale). It can run checkout and payment on a strongly consistent primary database.

Trade-offs

  • Choosing C (CP / EC): you get correct, predictable data. But you also get higher latency and errors or unavailability during partitions, especially across regions.
  • Choosing A (AP / EL): the system always responds and is fast. But you get stale reads and conflicts to resolve. Developers also find it harder to reason about.
  • Tunable systems: you can choose for each operation. But there are more ways to set things up wrongly. Teams must understand the settings that they choose.

Common mistake: choosing a database because its marketing label says "AP" or "CP". Instead, test how it behaves under the failures you care about, with your own settings.

In the Real World

Google Spanner. Spanner is built to be strongly consistent (CP) across the globe. It uses tightly synchronised clocks (called TrueTime) and consensus. Google has written that its private network is so reliable that partitions are very rare. So Spanner is effectively "CA" in practice, while formally it stays CP. When a partition does happen, consistency wins.

Amazon's shopping cart (Dynamo). Amazon chose availability. "Add to cart" should always work, even during failures, because refusing it means lost sales. Conflicting cart versions are merged later. This is a clear, deliberate AP choice for one specific feature.

DNS. DNS (the system that turns names into addresses) is a huge AP system. When a record changes, some resolvers keep giving the old saved answer until its TTL (time to live) ends (Lesson 1). The internet chose availability and speed over instant consistency.

Coordination services. Tools like etcd and ZooKeeper are used by Kubernetes and many databases to elect leaders and to store critical configuration. They are CP. If they cannot reach a majority, they stop accepting writes. They do this instead of risking two leaders. This is exactly the split-brain protection from Lesson 24.

Banking and payments. Moving money needs consistency. If the systems cannot confirm a balance or a transfer, you get "transaction failed, please try again". This is better than the risk of double-spending (spending the same money twice). Notification features or "recent transactions" views may lag a little, though.

Interview Questions

Q1State the CAP theorem precisely.

In a distributed system, when a network partition happens, you must choose between consistency (every read sees the latest write, which is linearizability) and availability (every non-failed node responds). Without a partition you can have both. CAP says nothing about normal operation.

Q2Why is “CA” not a meaningful choice for a distributed system?

Partitions are not optional. Networks drop and delay messages whether you like it or not. A system that assumes partitions never happen must still do something when one happens. That something is a choice of C or A.

Q3What does PACELC add?

It adds the everyday trade-off. If there is a Partition, choose Availability or Consistency. Else, choose Latency or Consistency. Strong consistency needs coordination (round trips to a quorum or to a leader). This costs latency even when nothing is broken.

Q4Is Cassandra AP?

With consistency level ONE it behaves AP-style. With QUORUM reads and writes it behaves much more like CP. A label depends on the settings and on the operation. So it is better to ask how a given operation, with given settings, behaves during a partition.

Q5How would you apply CAP to an e-commerce site?

Decide for each feature. Product pages, reviews and recommendations can be AP and served from caches and replicas. Reducing stock at checkout, payments and order creation must be consistent. They go to a primary or to a consensus-based store. If something fails, they show “please retry” instead of overselling.

Key Takeaways

  • CAP: during a network partition, a distributed system must choose consistency (refuse or wait) or availability (answer, maybe stale).
  • Partitions are not optional, so "CA" is not a real choice for distributed systems. Without partitions, you can have both C and A.
  • CAP's C means linearizability, not ACID's C.
  • PACELC adds the everyday trade-off: else, choose latency or consistency. Strong consistency costs coordination round trips.
  • Real systems are tunable. Decide for each feature how much staleness is acceptable. Test the real behaviour instead of trusting labels.

Further Reading

  • Eric Brewer's article "CAP Twelve Years Later: How the 'Rules' Have Changed" (IEEE Computer, 2012)
  • The paper "Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services" by Gilbert and Lynch (2002)
  • Daniel Abadi's paper "Consistency Tradeoffs in Modern Distributed Database System Design" (IEEE Computer, 2012), which introduces PACELC
  • Martin Kleppmann's article "Please stop calling databases CP or AP"
  • Eric Brewer's paper "Spanner, TrueTime and the CAP Theorem" (Google, 2017)
  • The System Design Primer on GitHub (section "CAP theorem")

Published by Jainik · Last updated · How these lessons are made

Keep learning

Part of the study guide

Related series