Monolith to Microservices
I had a recent discussion with my team on monolith versus microservices, and I recalled a series of conversations I had last year on the topic. I revisited my notes, and now want to consolidate some of my rememberings.
Start in a monolith
When you start a company, you have few engineers. You need to pivot quickly for product-market fit. You don’t have that much code. Everyone can know everything and work in the same codebase and it’s easier to change things in a monolith.
Establish firm domain boundaries BEFORE creating microservices
It is hard to change boundaries after the code is separated into microservices. Therefore, it is important that event-storming and bounded contexts are determined BEFORE the creation of microservices. It is important that the code is separated inside the same service and tested to make sure the boundaries are correct BEFORE it is separated into microservices. If you do not do this, you will end up with a series of microservices that comprise a distributed monolith. In a distributed monolith, everything is coupled together, more prone to consistency and availability issues (see CAP theorem) and latency, as you have to communicate across servers and databases. Additionally debugging due to decreased traceability/observability is harder.
Create microservices as code or traffic scales
There are benefits in having microservices, and the pros start to outweigh the cons as code/developers/traffic scales. If you want to scale one bounded context, now you don’t need to scale the entire monolith — you can just adjust that one microservice. It is easier to run tests for one system (just for that service). Additionally, each team can manage its own infra, without waiting for buy in from other teams.
Caveat 1: It is really hard to get bounded contexts right. Also. There are always going to be some contexts that are tightly coupled, or will be tightly coupled with other contexts. If there is a large chance this will happen as new business cases emerge, it might be good to stay in the monolith with tight separations enforced there.
Caveat 2: Having microservices does not necessarily mean you need event driven architecture. Event driven architecture does not necessarily mean you need event sourcing. These three things often come together, but they are separate and developers can choose one without having the other.
