2025-08-12 · Markian Mumba · Tech blog
Daily,Database,Distributed systems
This week, I stumbled on a few articles that got me thinking about scaling and managing large-scale databases. Inevitably, that takes you straight into the CAP Theorem conversation.
If you’ve been around database discussions long enough, you’ve probably heard it: you can only really have two of the three pillars — Consistency, Availability, and Partition Tolerance.
Now, picture this: your data is being copied across multiple replicas. The question is — how do you ensure that every replica has the same data, and users can access that data from anywhere without issues?
The simplest answer is synchronous replication — the original node only reports success after it gets acknowledgements from all the other replicas.
Sounds nice, right? Except there’s a catch.
Synchronous replication (or, more generally, anything synchronous) struggles with fault tolerance. Think of writing a program that compiles data and then sends an email synchronously. If the email service goes down, your entire program grinds to a halt. Your app loses availability because it’s waiting for something that may never come back up.
And that’s where Quorum enters the chat.
Wikipedia will tell you that a quorum is “the minimum number of members of a group necessary to constitute the group at a meeting.” But let’s bring that down to database land.
Imagine you have a database replicated across 3 servers. In this context, a quorum is the minimum number of servers that must confirm a read or write for the operation to count as successful.
For correctness, you need more than half of the replicas to agree. That means:
If there are N replicas, quorum = N/2 + 1.
For 3 replicas, you need at least 2 nodes to respond.
For 5 replicas, you need at least 3 nodes to respond.
Quorum-based reads and writes follow the golden rule:
┌───────────┐ │ w + r > n │ └───────────┘
Where:
w = number of replicas that must acknowledge a write
r = number of replicas that must acknowledge a read
n = total number of replicas
This ensures that the nodes you read from will always overlap with the nodes you wrote to — meaning you won’t accidentally serve stale data.
Let’s make this less abstract.
Scenario 1 — High Availability (N=3)
Say you only require 1 write and 1 read acknowledgement. That’s quick — you write to one replica, mark it as done, and read from one replica. But here’s the math:
w + r = 2, while n = 3.
That means you can easily read from a node that hasn’t gotten the latest data yet. Your app will be super fast and even survive if two nodes fail… but you’ll end up with weird moments like:
User adds an item to the cart
User reloads the page
Cart is empty because they’re reading from a stale replica
High availability, low correctness.
Scenario 2 — High Consistency (N=3)
Now, let’s say a write needs 2 nodes to acknowledge and a read needs 2 nodes to acknowledge. That’s w + r = 4, which is greater than n.
Here, you can tolerate one node failure, and reads are guaranteed to see the latest writes. The trade-off? Slightly slower performance. But your system is correct, and your users won’t think your app is broken.