How do you migrate a monolith to microservices?
This question has been making me sad for more than 10 years now.
First, the mainstream blindly believed in microservices (there is nothing better in the world).
Then it blindly believed in the modular monolith (we are not hipsters, we know the true way).
Meanwhile, reality on the ground has not changed one bit in the last decade.
Yes, hardware and software became commodities. DevOps culture emerged.
This freed us from SOA architectures built around proprietary software and expensive hardware. We finally got the ability to shape modules around business logic.
What did people do with that freedom?
They moved away from SOA โ good job. Money is a great motivator.
But instead of moving to microservices, they moved into a Frankenstein zoo, while still calling it microservices.
Modern system architecture is distributed. Period.
It is a mix of many patterns combined together. Microservices, microkernel, event-based, hexagonal, and many others.
And that is a good thing. Gang of Four taught us 30 years ago to be pragmatic with patterns.
Now, back from the rant ๐
The real question is different โ how do you migrate a monolith to a distributed architecture?
At a high level, there are two approaches.
1โฃ Business first
Often we move toward distributed architecture to achieve more efficient horizontal scaling. There are other reasons too, but I will use this one for simplicity.
This matters most for business-critical functionality. It makes sense to migrate what is most important first, then move on to less important parts (sometimes you never get to them, and that is totally fine).
But here is the problem.
What is most important for the business is usually the most popular functionality, with many dependencies.
Can you feel the pain already? When you migrate a component that many others depend on, you end up with a lot of moving parts, each one capable of breaking during the process.
2โฃ Dependency first
You build a dependency map for all components.
Then you migrate components with the smallest number of dependents first.
Visualize it. With each iteration, the number of dependent components decreases. By the final iteration, the component that once had many dependents now has almost none.
Sounds like a silver bullet. So why do not we always do it this way?
Because it is very hard to explain to the business why the most important functionality will be migrated last ๐
We already know there is no single effective solution for all architectural problems.
So in every migration, we juggle both approaches, and sometimes, rarely, we even use them simultaneously.
In the end, this is a question of risk management and the costs that come with it.



Great framing of the migration dilemma. The dependency-first vs business-first tension is somthing that never gets enough airtime in architecture discussions. I've been in situations where we started dependency-first and hit a wall when stakeholders realized critical features were stuck in monolith limbo for months. The Frankenstein zoo comment is spot-on, most distributed systems I've worked with are hybrid architectures that nobody admits aren't pure microservices. Risk management is the real game here,not pattern purity.