Skip to main content

Command Palette

Search for a command to run...

CAP Theorem Explained

Updated
6 min readView as Markdown
CAP Theorem Explained

So these days, I’ve been learning about system design to practice and brush up on my skills, and also to refresh my memory of how complex systems—or even any system—work under the hood.

System design is one of the building blocks of almost everything you’ve seen on the internet. I’m specifically talking about software stuff here, so please, nobody come and shout at me about physical items.

Basically, in any software, a good and solid system design is needed to make sure that the software works properly and serves its users well.

A good, well-thought-out system design before jumping into development can save you a lot of time and prevent your product from eventually running into those 3 AM production issues where most DevOps people cry and say they have to work at night because some merge broke the entire production environment.

Okay, that was me trying to crack a really bad joke, but it’s actually a much more serious issue than my bad joke makes it sound.

Imagine you sell some kind of magic wand, like the ones shown in Harry Potter. You have users in the United States, while you’re operating from India or another country where the time zone is completely different.

Now, imagine that a user is trying to make a purchase, but your payment service breaks because too many people are hitting your servers at the same time.

So what happens?

You start losing potential customers and revenue.

And who actually likes losing money?

I really don’t, and hopefully, no one does.

So, what’s the solution?

Ahh, it’s very simple. I guess I’ve already made it pretty easy to guess: better system design.

And when I say better system design, I mean things like properly distributed services, load balancing, fault tolerance, high availability, scalability, failover when one service goes down, proper database sharding or partitioning—basically, whatever your system actually needs.

A lot of the terms above might feel unfamiliar to you. If that’s the case, this might not be the best article to start with, and I would advise you to first look for something like System Design for Beginners.

But if you understand most of the terms above, then please carry on reading.

Whenever you’re designing a distributed system, you might have heard about the CAP theorem. And if you haven’t heard about it yet, hopefully, you’ll understand it by the end of this article.

Basically, the CAP theorem describes three important properties of a distributed system:

Consistency — All nodes/users see the same data at the same time.

Availability — Every request receives a response, even if that response does not contain the latest data.

Partition Tolerance — The system continues operating despite network failures between different parts of the system.

These are the three properties involved in the CAP theorem.

The important part is that when a network partition actually occurs, a distributed system has to choose between maintaining Consistency and maintaining Availability.

Partition tolerance is generally unavoidable in distributed systems.

Why?

Because network failures can happen.

Let’s take the example of X, formerly known as Twitter.

Imagine that one part of X experiences a network problem. Maybe one group of servers cannot communicate properly with another group.

The system now needs to decide what it should prioritise while that network partition exists.

Should it continue serving users, even if some of them temporarily see slightly outdated data?

Or should it refuse some requests until it can guarantee that everyone sees the latest data?

That is where the trade-off between Consistency and Availability comes in.

Let’s understand both in more detail.

Consistency

Continuing with our X example, consistency means that users should see the same, most recent data regardless of which node they are connected to.

Let’s say User A posts a new tweet.

Because of a network partition, one server knows about the new tweet, while another server does not.

Now User B sends a request to the server that has not received the latest update yet.

If we prioritise consistency, we should not return stale data as if it were current.

Instead, the system may reject or delay User B’s request until it can guarantee that User B receives the correct and latest version of the data.

In simple terms:

“If I can’t guarantee that the data is correct and up to date, I’d rather not give you an answer yet.”

That is the consistency side of the trade-off.

Availability

Availability, on the other hand, says:

“Even if I cannot guarantee that you’re seeing the latest data, I will still give you a response.”

So, in the same example, User B might temporarily see an older version of the timeline because the server they are connected to has not yet received User A’s latest tweet.

But the application continues working.

The user can still open timelines, read tweets, and interact with the platform.

The data might be slightly stale for a short period of time, but the system remains available.

So now, there isn’t necessarily one universally correct option between consistency and availability.

It depends on how you want your software or product to behave.

For something like X, availability can often be more important for many features.

Users should still be able to open the application and read tweets, even if some of the information they see is a few seconds behind.

But now let’s take something more sensitive.

Imagine a movie-ticket booking platform such as BookMyShow.

Suppose there is only one seat left for a movie.

User A selects that seat and starts the booking process.

At almost the same time, User B also tries to book the same seat through another server.

If those two servers temporarily disagree about whether the seat is available, both users could potentially be allowed to book the same seat.

That would obviously be a problem.

Two people cannot have the same physical seat.

So for operations like seat allocation, systems generally need much stronger consistency guarantees.

You would rather tell User B:

“Sorry, we cannot confirm this seat right now.”

than incorrectly sell the same seat twice.

The same idea becomes even more important in systems involving money, inventory, banking, or other operations where incorrect data can have serious consequences.

There can be many other examples where you choose one trade-off over another, but ultimately, it depends on how you want your software to behave during failures, rather than blindly choosing one property over another.

And that, in very simple language, is the basic idea behind the CAP theorem.

If you want to go deeper and learn more about system design concepts, give me a follow and stay tuned.