Killing the Monolith
By: Peter Kogan
Tags: Startup, Ai And Data Science, Monolith

Setting the stage: it has been three years (and counting) for Check, a startup that was doing OK with its Monolith but we adapted our mindset to new architectures when we became part of Intuit.

Unlike to what you might have imagined, many startups do have monoliths: despite the common belief that they are young, innovative and don’t carry legacy code. Some veteran corporations, which might have decades old code and are called ‘dinosaurs’ or other unflattering metaphors, are actually in the process of or have already undergone a transformation to micro services.

What is a Monolith?

A Monolith is a natural growth of a code project.

It starts with a small piece of code to do some specific work. Sounds simple enough, isn’t it? Then comes new requirements and the obvious solution is to add more and code to the project. The process continues and the once small project has multiple modules, which are all tightly bundled together.

Hence the name: Monolith.

Why would a company want to kill a Monolith?

Monoliths have one trait which makes them very appealing: it offers access to EVERYTHING and the ability to debug, compile and deploy your application to a single machine.

This works great for small teams and companies: every developer can access any part of the system. It’s easy to do end-to-end features without needing the help of external resources. You are the master of your fate and all one small, happy family.

As things get bigger, this advantage comes with significant drawbacks: having the ability to touch anything means any developer might break something you care about. Communication done through non-formal APIs (like DB) is bound to break when a change is introduced.

If you have multiple teams working on the code base, things get worse: a single developer can stop the deployment for all others by breaking the compilation or automation. Teams are prone to know only specific areas of the monolith so they can’t fix other areas and are more bound to break them (but are crippled if any of them is broken).

Another drawback is the inability to integrate with 3rd parties and to extend your product: Monoliths are good with doing a dedicated, narrow task. That’s what they are built for. If you try to open your code/API/functionality to a 3rd party, you will find that even a small change affects many areas in the system, since they are tightly coupled. You would find yourself wasting a lot of time and moving at a very slow velocity.

The bigger the Monolith, the worse it gets.

So why is it bad for a corporation? A corporation is made up of a lot of teams doing a lot of work in various domains. It’s your Monolith problem, magnified 100 fold. You cannot expect all engineers and all teams to know or even care about every piece of the software, so the only way is to break it down to many little self-contained services.

Startups move as a single unit. They have one or very few goals to focus on at every given time. Corporations do a lot of things and have multiple teams, so by definition not all individuals have the same priorities. With Monoliths you can change every bit of your software for any feature you introduce, but you are forced to do a cross sweep every time. This is precisely why Monoliths are good for single purpose startups but don’t scale to larger corporations.

Startups have very little to lose, especially if they don’t move fast enough before their funds run out. Corporations have a lot to lose but they have the funding to keep them floating for longer time. From end-to-end ownership, you get to limit the impact (damage and risk).

From a small family where everything is the business of everyone, to multiple groups which run in parallel and have different goals, that is what the change is about.

How to actually kill it?

Killing Monoliths is hard. Very hard. It involves ripping out major parts of your application, redesigning them and converting them into self sustaining systems. Not only that, in most cases you probably have a live production system which you cannot break during the (quite long) process.

The first thing you have to do is to commit to the change: realize that you can no longer continue with the way things are working right now. Moving from a Monolith to a micro services architecture is a process which takes many months to complete and, once it has started, there is no going back.

Besides the shift in architecture, you have to be prepared for a resource shift, i.e. Organizational Changes. Yes, I know this sounds scary and nobody wants to talk about these changes, but services architecture and mindset has to be backed up with org structure. You want every one of your engineering teams to own self contained pieces of your software to limit the amount of dependencies.

Once you get to the realization and are willing to commit and pull through with the technical and organization changes, the basic prescription is pretty easy:

1. Find a relatively self-sustained module

2. Organize your team to write it as a service

3. Use feature flags to safely migrate to the new code

4. Go back to step 1

One day, if you do this long enough, you would find all Monoliths slain, rewritten, decommissioned and mostly forgotten. You will also find that your organization has gone through a fundamental change: from a tight family pursuing very narrow objectives to many groups working side by side.