Day to day application of the CAP theorem

When someone explains the CAP theorem, they do it in the context of distributed data stores. But, if you understand the CAP theorem’s essence, you can use it in your day-to-day application design.

Nowadays, most applications(even rudimentary ones) are distributed applications—they invoke external APIs and services. Hence, understanding and applying the CAP theorem to application design is crucial for building robust applications.

CAP theorem says that you have to choose either consistency or availability in the face of network failures; you cannot have both.

CAP theorem is the programmer’s version of you cannot have your cake and eat it too.

Let us take a hypothetical application that exposes an API to register a user. For storing the user data, the application uses two datastores—MongoDB and MySQL. The datastores and the application backend are on different servers. When the client invokes the user registration API, the backend makes a network call and stores the data in MySQL and MongoDB.

For the sake of this post, I will define application availability as the backend returning a success response. I will define application consistency as the user data being available in MySQL and MongoDB on a success API response from the backend.

The above definitions are not strictly in line with the definitions of availability and consistency, as defined by the CAP theorem. I am taking liberties to convey the idea.

Designing the application using the CAP theorem

The backend and the datastores are on different servers. Since network failures are a given, the datastores might become temporarily unavailable to the backend. How should the application behave during network glitches?

Let us work with a specific scenario.

The client invokes the API; the payload reaches the backend, and the backend is trying to store the data in MySQL and MongoDB. The backend successfully stores the data in MySQL, but the backend cannot access MongoDB due to a temporary network failure.

You can design your application in two ways to handle this scenario.

Design option one

The backend stores the data in MySQL and returns a success response to the client. A periodic reconciliation job runs that queries MySQL, compares the data with MongoDB, and inserts the missing records into MongoDB.

With the above design, your application favors availability over consistency. When there are network failures, the backend is available(does not throw an error), but the data is inconsistent(present in MySQL but not in MongoDB). With this design, the application is eventually consistent—once the reconciliation job runs, the application becomes consistent.

Design option two

The backend returns an error response to the client when there are network glitches(when backend cannot communicate with the datastores). You put the onus on the client to retry under such circumstances.

With this design, your application favors consistency over availability. The application does not return a success response when it cannot store the data in both MongoDB and MySQL. You do not need reconciliation jobs in this design.

Every application these days is a distributed application. Hence, you need to understand the CAP theorem and use the CAP theorem’s essence while designing applications and thinking about the tradeoffs.

PS—To simplify the explanation and make it accessible, I have washed down the CAP theorem and the application failure modes. I will write a follow-up post, expanding the idea, and make it rigorous.

Get articles on coding, software and product development, managing software teams, scaling organisations and enhancing productivity by subscribing to my blog

Diagram created using the amazing

Small company advantage

Below tweet appeared on my timeline.

The tweet brought back a quote(paraphrased from memory; I do not know the author).

Every employee does two jobs. The job and the job to prove that they are doing the job.

Arduous performance reviews, stakeholder management, timeline-based project managementlong term project planningjustifying project delays, and creating visibility are typically the work that one does to prove that they are working.

In a big organization with multiple layers of management and divisions, it might be tough to avoid these. There is no reason why a small business should follow the same policies and work style. Small companies should be optimizing for output.

A big business CEO has to be a master capital allocator. A small business CEO has to be a master resource allocator. Small businesses are perennially short of resources. An employees’ time is one of the most scarce and valuable resources for a small business. A small business should do whatever it can to maximize employees’ productive time. That means cutting all the things that people do to prove that they are adding value.

A small business’s competitive advantage comes from creating an environment where employees can spend their time creating value instead of posturing.

Get articles on coding, software and product development, managing software teams, scaling organisations and enhancing productivity by subscribing to my blog

Photo by Engin Akyurt from Pexels

Do not rage against the machine

In life, we have to do many pointless things; at least pointless for us.

We have to fill unnecessary forms.
We have to get documents signed by random people.
We have to write foolish things.
We have to take part in pointless activities.
We have to follow senseless social norms.
We have to run behind people, asking them to address issues they should be pro-actively solving.

It is frustrating to go through this. When this happens, you feel the entire world is teaming against you. The sleeping rebel within us wakes up and wants to rage against the unfair world.

Do not let this happen.

If only raging solves problems. Instead, raging aggravates it. You lose agency of the task at hand—your brain switches from problem-solving to complaining mode. And, we will know how that turns out.

We usually get to know when our brain starts flipping. But, we do not try to stop it; we fuel the rage with an internal monologue of how unfair all of this is. The way to prevent this is by taking ownership of the task. You anyways have to do it, why not own it and finish it off quickly? When you take ownership of something, your brain finds innovative ways to hack through the task.

Do not rage against the machine; be the mechanic who fixes the machine.

Get articles on coding, software and product development, managing software teams, scaling organisations and enhancing productivity by subscribing to my blog

Image from Wikimedia.