Monolith & Microservices – Understanding The Trade-Offs – Part 1

So, in this chapter, by now, we have understood what is a monolith, what is a microservice, their pros & cons & when to pick which? In this lesson, we will continue our discussion a bit further on the trade-offs that are involved when choosing between the monolith and the microservices architecture to design our application.

Fault Isolation

When we have a microservices architecture in place it’s easy for us to isolate faults and debug them. When a glitch occurs in a particular service, we just have to fix the issue in that service without the need to scan the entire codebase in order to locate and fix that issue. This is also known as fault isolation.

Even if the service goes down due to the fault, the other services are up & running. This has a minimal impact on the system.

Development Team Autonomy

In case of a monolith architecture if the number of developers and the teams working on a single codebase grows beyond a certain number. It may impede the productivity and the velocity of the teams.

In this scenario, things become a little tricky to manage. First off, as the size of the codebase increases, the compile-time & the time required to run the tests increases too. Since, in a monolith architecture, the entire codebase has to be compiled as opposed to just compiling the module we work on.

A code change made, in the codebase, by any other team has a direct impact on the features we develop. It may even break the functionality of our feature. Due to this a thorough regression testing is required every time anyone pushes new code or an update to production.

Also, as the code is pushed to production, we need all the teams to stop working on the codebase until the change is pushed to production.

The code pushed by a certain team may also require approval from other teams in the organization working on the same codebase. This process is a bottleneck in the system.

On the contrary, in the case of microservices separate teams have complete ownership of their codebases. They have a complete development and deployment autonomy over their modules with separate deployment pipelines. Code management becomes easier. It becomes easier to scale individual services based on their traffic load patterns.

So, if you need to move fast, launch a lot of features quick to the market and scale. Moving forward with microservices architecture is a good bet.

Having a microservices architecture sounds delightful but we cannot ignore the increase in the complexity in the architecture due to this. Adopting microservices has its costs.

With the microservices architecture comes along the need to set up distributed logging, monitoring, inter-service communication, service discovery, alerts, tracing, build & release pipelines, health checks & so on. You may even have to write a lot of custom tooling from scratch for yourself.

So, I think you get the idea. There are always trade-offs involved there is no perfect or the best solution. We need to be crystal on our use case and see what architecture suits our needs best.

Let’s understand this further with the help of a real-world example of a company called Segment that started with a monolith architecture, moved to microservices and then moved back again to the monolith architecture.

Segment – From Monolith To Microservices And Back Again To Monolith

Segment is a customer data platform that originally started with a monolith and then later split it into microservices. As their business gained traction, they again decided to revert to the monolith architecture.

Why did they do that?

Let’s have an insight…

Segment engineering team split their monolith into microservices for fault isolation & easy debugging of issues in the system.

Fault isolation with microservices helped them minimize the damage a fault caused in the system. It was confined to a certain service as opposed to impacting, even bringing down the entire system as a whole.

The original monolith architecture had low management overhead but had a single point of failure. A glitch in a certain functionality had the potential to impact the entire system.

Segment integrates data from many different data providers into their system. As the business gained traction, they integrated more data providers into their system creating a separate microservice for every data provider. The increase in the number of microservices led to an increase in the complexity of their architecture significantly, subsequently taking a toll on their productivity.

The defects with regards to microservices started increasing significantly. They had three engineers straight up just dedicated to getting rid of these defects to keep the system online. This operational overhead became resource-intensive & slowed down the organization immensely.

To tackle the issue, they made the decision to move back to monolith giving up on fault isolation and other nice things that the microservices architecture brought along.

They ended up with an architecture having a single code repository that they called Centrifuge that handled billions of messages per day delivered to multiple APIs.

Let’s have a further insight into their architecture in the lesson up next.