CAP, PACELC and consistency models

Lesson 4.5 · 7 min read · by Vinay C

We'll cover the following

CAP, precisely

  • Partition (network failure between nodes) is a given, not a choice. CAP really says: when a partition happens, choose C or A. With a healthy network you can have both. "Pick 2 of 3" oversimplifies.
  • CP: refuse or error rather than return a possibly stale answer (payments, inventory).
  • AP: always answer, maybe stale (feeds, likes).
  • Eventual consistency is not just for read-heavy systems. It is about what staleness you can tolerate.
  • Strong: the 200 means the write is on enough replicas (usually a quorum) that any later read sees it. Eventual: the 200 comes after one replica has it and the others catch up.

PACELC (say "pass-elk")

If Partition, choose A or C. Else, choose Latency or Consistency. Even when healthy, waiting for more replicas gives better consistency but slower responses. DynamoDB default reads are fast and eventually consistent; Spanner is consistent but pays in latency.

It is a setting, not a product label

  • Postgres with a single primary and sync replicas behaves CP. With async replicas, replica reads are stale (eventual) but writes still stop if the primary dies.
  • Distributed SQL (Spanner, CockroachDB) is firmly CP.
  • Cassandra with QUORUM reads and writes acts CP for that query; drop to ONE and it is AP.
  • DynamoDB and Cassandra let you pick per query.

Quorum

Data is copied to N replicas (say 3). W = replicas that must confirm a write, R = replicas you ask on a read. If R + W > N the read and write groups overlap in at least one replica, so a read always touches a node with the latest write. N=3, W=2, R=2 gives strong consistency and still survives one node down. W=1, R=1 is faster but can read stale.

Read-your-own-writes

User changes their profile picture: others may see the old one for a few seconds (eventual is fine), but the user must see the new one immediately. It is a session guarantee. Get it by reading the user own data from the primary for a short window after they write, updating the UI optimistically, or passing a version/timestamp so a lagging replica refuses to serve.

What CP vs AP changes beyond a toggle

  • Replication: synchronous (CP-ish) vs asynchronous (fast, AP-ish).
  • Quorums: choose R and W.
  • Failure behavior: reject during a partition vs keep serving stale.
  • Conflict handling (AP): both sides accepted writes, so you need last-write-wins, vector clocks or CRDTs.
  • Caching: TTLs and invalidation are consistency decisions. Cache seat availability for display with a short TTL, but never trust the cache for the booking itself; the final check hits the DB in a transaction.
  • Multi-region: single leader or active-active (below).
  • Cross-service flows: 2PC or sagas (next section).
  • UX: optimistic UI, "pending" states, retries and idempotency.

Multi-region: single leader vs active-active

Single leaderActive-active
WritesAll go to one region (e.g. US); far users pay ~200msEach region accepts writes locally
ProsOne source of truth, no conflictsFast everywhere
ConsSlow for distant usersSame record edited in two regions at once means conflicts you must merge
FitsTicket bookingCollaborative or feed-like data

Pick consistency per piece, not per system

  • A common mistake is answering a CAP question with one word for the whole system: "I pick availability." Real systems are made of many small pieces, and each piece can choose differently.
  • The questions to ask: which piece of data must everyone agree on, and how big is that piece? For a chat app, the thing that must agree is the order of messages inside one conversation. It does not need to agree across all conversations in the world.
  • So give each conversation a single owner (one server that numbers its messages). That owner is what keeps the order consistent.
  • Now the partition case: if that owner is unreachable for a moment (a crash, a failover), that one conversation briefly stops accepting new messages rather than risk two different orders. That is the consistent (CP) choice, but only for that one conversation.
  • Every other conversation has its own owner and keeps working, so the system as a whole stays available.
  • Say it like this: "I would not pick CP or AP for the whole system. Order has to be consistent per conversation, so a conversation pauses during its owner failover, while every other conversation stays up."
  • Details of how the owner numbers messages: see Ordering, acks and delivery guarantees.

Summary: say it in the interview

  • "I pick consistency per feature. Payments and inventory are CP with sync replication. Feeds and likes are AP with async replicas, and I add read-your-own-writes for the user own actions."