From Monolith to Microservices: A Pragmatist's Guide
When decomposition helps, when it hurts, and how to tell the difference.
Microservices are the answer to a specific question: 'How do we scale team autonomy and deployment independence for a system that has genuinely outgrown a single codebase?' If that's not your question, microservices are not your answer.
When Monoliths Are Correct
A well-structured monolith with clear module boundaries, a disciplined data layer, and a CI/CD pipeline that deploys in under 10 minutes is genuinely competitive with a microservices architecture — and dramatically simpler to operate, debug, and evolve.
- Team size under 15 engineers: organisational overhead of service ownership is not worth it.
- Domain not yet understood: decomposing too early freezes incorrect boundaries in distributed contracts that are expensive to undo.
- No dedicated platform/infra capability: microservices require operational maturity that most product teams underestimate by 10x.
"The microservices you build in year one will be the monolith you're decomposing in year three — because you didn't understand the domain yet."
When Decomposition Is the Right Move
The trigger for decomposition isn't scale — it's organisational friction. When two teams are blocked by each other's deployments, when the same module is the critical path for six different features, when testing has become so slow that developers avoid it — that's when service extraction pays off.
A Migration Pattern That Works
- Strangle Fig pattern: route a specific traffic type to a new service while the monolith still handles everything else.
- Domain-first decomposition: extract by business capability, never by technical layer.
- Shared-nothing data: two services that share a database are one service.
- Event-sourced boundaries: use events, not direct calls, for cross-service communication.