The birth of a monolith (Splitting a Monolith Part 1)

The birth of a monolith (Splitting a Monolith Part 1)

"Rise of Monoliths" by ksajler (CC BY-SA 2.0)

This is the first and introduction post in a multi-part series on how we’re splitting the monolith that powers the customer-facing backend written in django into smaller services.

The Birth of a Monolith

In the beginning of TIER, we had licenced car-sharing software that was bent to support our scooters. It turned out that scooter sharing and car sharing have vastly different requirements. The issue was that the car-sharing software couldn’t handle the number of vehicles we had on the street. That’s why we wanted to replace the licensed software with our own, custom-built to solve our problems.

Rise of Monoliths by ksajler is licensed under CC BY-SA 2.0

At that time, we only had a handful engineers working on everything. There was also a tight deadline: just three months before summer, the busiest season for the business. Our system requirements were initially simple. The system should be able to provide the following capabilities:

Even though there is a clear distinction between the domains, they all live inside the same monolith
Even though there is a clear distinction between the domains, they all live inside the same monolith

  • rentals
  • invoicing
  • billing
  • customer support backend
  • a few other core features

We didn’t have a standard infrastructure pattern at the time, and our first version of the app was hosted on Heroku. Our codebase grew from a few hundred lines of code to about 70k lines of code, eventually becoming our largest monolith. But it didn’t become a monster overnight.

How a Service becomes a Monolith

Our customer-facing backend was built in django, as django was what we knew best. And it’s truly “The web framework for perfectionists with deadlines”, as it says on the box, but of course it comes with its own caveats. And we surely had a deadline, so it had to be a good match!

As all developers, we are lazy. After having built the first part of the service and deployed it into production, we did not ask ourselves where the next line of code should live. It’s only natural that we took the easy path – the path of the least resistance – when adding new domain models and features to this service.

The framework you are using is also contributing directly to that path of least resistance. In the case of django, the initial setup is rather complex, but once everything is setup it is very easy to add new models and to make database migrations. So it was always easier to add a new database table, than for example to create a new service.

A monolith does not appear overnight, it grows over time. We were thinking about shipping software and not about that one day multiple teams would work on each separate topic. Moreover, since our deadline was coming closer and closer, there surely was no time to split up the topics into multiple, specialized services.


To wrap up, we still believe we made the right call, given the time and resources we had back then. From today’s perspective, we think we could have made our future lives easier, but hindsight is as always 20/20. In later installments of this series, we will go into detail on which choices would have helped us now, each by example. The final installment of the series will give you an overview of the dos and don’ts when building a monolith when starting a new project.

Loading open positions...
The birth of a monolith (Splitting a Monolith Part 1)
Older post

Hello World

Newer post

Monolith vs Microservices (Splitting a Monolith Part 2)

The birth of a monolith (Splitting a Monolith Part 1)