Start with a modular monolith, not microservices
By Ahmad Badr
Every few months a team asks us to build them microservices. Almost every time, what they actually need is clear module boundaries, not a distributed system with the operational tax that comes with it.
The cost you pay on day one
Splitting a system across the network buys you independent deployment and scaling. But you pay for it immediately: distributed transactions, network failure modes, versioned contracts between services, and a deployment topology that a small team spends more time operating than improving.
- Every in-process call becomes a network call that can fail, retry, or time out.
- A single feature now spans multiple repos, pipelines, and dashboards.
- Local reasoning gets harder: you can no longer step through a request end to end.
A modular monolith gets you 90% of the benefit
A modular monolith enforces the same bounded contexts (identity, billing, notifications) as separate modules with explicit interfaces, but keeps them in one deployable. You get clean seams without the distributed-systems bill.
Design the boundaries first. If a module later needs to scale independently, you extract it, and the interface is already there.
When we do split
Independent scaling profiles, team ownership at organizational scale, and genuinely different reliability requirements are all real reasons to extract a service. The point isn't to avoid microservices forever; it's to earn them, one boundary at a time, instead of paying for all of them up front.
Have a project like this?
We help teams architect, build, and ship software that keeps running. Let's talk about what you're building.
Start a conversation
