Pick Two Is a Lie: CAP, Consensus, and the Root Cause of Split Brain
- BY
- ROOT TEAM
- PUBLISHED
- AUGUST 30, 2026
- READING TIME
- 10 MIN READ
CAP was never a menu. When the network cuts, you don't get to choose a virtue. You make one forced choice. Here is what the theorem actually says, why consensus exists, and the single sentence behind every distributed systems horror story.
Every company has a version of the same bad day in distributed systems. A checkout double-charged someone. A failover promoted a replica and lost a week of committed writes. A shopping cart quietly dropped an item overnight. Each postmortem named a different culprit, and they were all wrong in the same way.
Trace any of these backwards and the answer stops looking like an infrastructure detail. It stops looking like your stack at all. Every one of these stories ends at the same point: two machines both believed they were telling the truth, and nothing in the system could decide which one was right.
That is the moment this post is about. The CAP theorem describes it, and a family of algorithms called consensus was built to fix it. You have met them as Paxos, Raft, and the databases those ideas live inside. The real CAP is not the menu most of us were taught. Once you see the difference, a lot of your outages will start making sense.
The menu that was never a menu
The usual version goes something like this. CAP says a distributed system can only give you two out of the three things Consistency, Availability, and Partition tolerance. So pick the two you want. That sentence gets exactly one word wrong, and it's the word pick.
Partition tolerance is not a choice. It's physics. The moment you run on more than one machine, a switch can die, a cable can get cut, a node can stall so long that its peers have to assume it's gone. The network between them stops delivering messages, and that happens whether you picked it or not. You already chose P the day you ran two processes. So did everyone else.
What actually happens when the network cuts
So let's look at that moment. Two halves of your system can't hear each other anymore, and a write shows up on each side. Now you have exactly two moves, and both of them cost something.
- Both sides accept the write. The system stays available. Each half keeps its own history, out of sight of the other. When the partition heals, you have two versions of the truth that disagree, and somebody has to reconcile them or pick a winner. That's split brain.
- Only the majority side accepts. The minority refuses writes it can't confirm. The system keeps one single truth, but that half of the system is down until the network comes back.
That's the whole theorem. During a partition you're not choosing two out of three virtues. You're making one forced tradeoff: stay up and risk two truths, or keep one truth and take a side offline. What the theorem actually forbids is the thing everyone means when they say pick two. Both sides keep accepting writes while the whole system still serves one consistent answer. The network broke the communication those guarantees depended on.
The menu framing makes CAP sound like a personality quiz. It's more like a diagnosis. If the word consistency shows up in your design, you've already made one of these two moves.
Every horror story has the same source
Run the five-step trace on the three disasters from the opening. The pattern comes out exactly the same every time.
Symptom: shopping cart lost an item overnight
why
Surface: a write landed on a replica that lagged behind
why
Layer 2: reads were routed freely and never checked the
copy had been confirmed by the writer
why
Origin: reads had no rule that admitted only confirmed writes
Symptom: customer charged twice
why
Surface: a payment gateway retried an idempotency key
why
Layer 2: the idempotency check read a stale replica
why
Origin: a node answered a yes/no promise without
confirming the answer had stuck anywhere
Symptom: failover promoted a new leader, then lost writes
why
Surface: the old leader came back and split opinions
why
Layer 2: the promoted node had not even held the full log
why
Origin: promotion did not require a quorum to agree on
what had already been committed
Three unrelated postmortems, one cause, dressed up three different ways. Look closer and they're really two failures wearing costumes, and together those two are every distributed systems failure we've ever seen take a team down:
- Phantom acknowledgment. A node reported success it hadn't earned. It said yes, wrote a promise, reserved a seat, finished an idempotency check, but it never confirmed with a quorum that the fact would actually stick.
- Divergence. Two nodes each acted like they were the truth. They accepted writes, promoted leaders, served reads, while some part of the system still believed there was only one answer.
Two nodes both believed they were the truth. Everything else in the postmortem is a costume.
Consensus algorithms exist to make both of those impossible.
The fix has a name: consensus
Consensus is a procedure that lets a group of machines agree on one thing, even while some of them are dead, slow, partitioned, or outright lying, and record that agreement so it can be verified later. The version engineers can actually read is Raft, and its bets are simple.
The nodes elect one leader, and the leader owns the entire log. That log is the single ordered history of everything the system accepted. Every new entry gets appended to the leader's log and pushed out to as many followers as can store it. An entry is only committed when a majority of nodes hold it.
The majority is the trick, and here's why it works. Any split of a cluster leaves two majorities that overlap in at least one node. Five nodes can only divide into three and two, and a three and a three always share a member. So anything a majority has agreed on, the next leader can prove by finding that overlap and inheriting its log. Two sides can never both claim the same commit, because two majorities always share one node that remembers what was really agreed.
Then there's the detail that does all the quiet work: the term number. Every election bumps the term, and every node refuses decisions from older terms. A leader cut off from the majority keeps talking, but every node that has seen a newer term ignores it. A minority leader can't fake a commit, because a commit needs a majority, and the majority has moved on.
Read Raft and you'll see what it is at heart: an algorithm that makes agreement boring. "Trust me, I saw it" becomes "a majority holds a copy, and the term says I'm allowed to speak." The phantom ack is gone. The divergence is gone. Split brain doesn't happen anymore, because split brain requires two sides both believing they were right, and the term number makes one side provably wrong.
What consensus doesn't change
One clarification that trips nearly everyone up: consensus does not violate CAP. During a real partition the minority side still can't commit, so it still can't serve writes. You haven't gained availability during a partition. You've gained honesty. The system refuses to be two truths, and it can prove the single truth it keeps.
None of this is exotic. Postgres under synchronous replication with quorum commit, etcd, ZooKeeper, most systems that call themselves durable. They all run the same idea underneath: nothing is promised until enough copies agree, and the answer survives a leader's death. That's also why "never build your own Raft" isn't gatekeeping. It's a warning that the hard problem is already solved and boring, and boring is exactly what you want in a foundation.
That's the first half. The second half is where the business actually decides, and it matters more than the algorithm.
Consensus is a product decision
Consistency isn't a technical setting. It's a product decision about what a user loses if two nodes briefly disagree. Nothing should be consistent or eventually consistent in the abstract. The real question is whether this specific fact, the one in front of you, is allowed to diverge.
Take a view count, a like, a trending feed. Two users briefly see different numbers and nobody is harmed. Eventual consistency is the right engineering there, and forcing quorum on it just buys latency for a guarantee no user ever experiences.
Now take a balance, a seat, an inventory count, an idempotency promise, the answer to "did I already send this?" If two nodes disagree there, a user gets double-charged, a flight gets double-sold, a coupon gets double-spent. That's not a technical bug. The product is broken.
The test is the same one we run on every product we build: trace the failure to what the user loses.
Divergence is fine: views, likes, drafts, notifications, analytics
Divergence is fatal: balances, seats, inventory, idempotency,
identity, money, anything a retry would
rather fail than repeat
Every real system already made this call. Stripe never lets two nodes own a payment. A chat app lets two devices briefly disagree about read state. Both are right, and neither is more correct about the theorem. They just made different product decisions about which side of the split brain they could afford.
The checklist before you add a second node
CAP stops being trivia the day your system crosses one machine. Before you add the second replica, the cache, the queue, or the second region, run through these:
- The network cuts this minute. Which side of the system keeps accepting writes?
- What does that side confirm before it says yes? Or does it promise things it can't prove?
- If both sides accept, what reconciles them, and who pays for the divergence until it does?
- Is there one named source of truth per fact, ordered and single? Or would two engineers give different answers to "what is the source of truth for a balance?"
- For every fact where a split hurts a user, is consensus on the critical path, not in a sync job that runs sometime later?
And the honest closer. You almost never need to write a consensus algorithm. You need to stop letting a node promise what it couldn't prove. No algorithm fixes a design that allowed two machines to both be right.
Try it on your last outage
Take the last incident that needed a war room, or the one nobody could fully explain, or the one you're tired of re-explaining. Answer two questions from memory. Did any node report success it hadn't earned? And did any two nodes disagree about who owned the truth?
One of those two sentences is your root cause. The rollback script, the retry, the alert threshold, the dashboards, they're all symptoms. Name who was allowed to be right, fix that, and the whole postmortem collapses to a single line.
If you'd rather hand us the incident, that works too. Finding the cause is our daily work.
Related reading: From Symptom to Source walks the five-step trace we run on every problem before any fixing code is written.