The Architecture Everyone Wants and Almost Nobody Needs
Walk into any engineering org's roadmap meeting and someone will eventually say it: "we should really break this into microservices." At this point it's basically a rite of passage, the thing you do once your codebase feels big enough to be embarrassed about. But most teams adopt microservices for the wrong reasons, at the wrong time, and the bill doesn't come due until eighteen months later, when it's much harder to undo.
So let's talk plainly about when microservices actually make sense, and when they're just distributed complexity wearing a nicer outfit.
What Microservices Actually Trade Away
A monolith gives you one codebase, one deployment, one database transaction boundary, and a debugger that can step through your entire request path in one place. Microservices trade all of that for independent scaling and deployment. In exchange you get network calls where function calls used to be, distributed data consistency to worry about, and a debugging story that now runs through five services and a tracing dashboard instead of a stack trace. None of this is a knock on microservices. It's just a reminder that every architectural decision is a trade, not an upgrade. You're not leveling up when you split a monolith. You're choosing a different set of problems, and it's worth being honest about which set you'd rather live with.
When Microservices Genuinely Win
- Different parts of your system scale wildly differently. If your image-processing pipeline needs 50x the compute of your user-settings page, coupling them in one deployable is wasteful.
- Multiple teams are stepping on each other. When 40 engineers are shipping to the same monolith and merge conflicts and deploy queues are slowing everyone down, service boundaries can restore team autonomy.
- You need independent failure domains. A crash in your recommendation engine shouldn't take down checkout. Microservices let you isolate blast radius.
- You have genuinely different technology needs. A service doing heavy numerical computation might benefit from a different language or runtime than your web layer.
When It's a Trap
- You have fewer than about 15 to 20 engineers. The coordination overhead of microservices often costs more than it saves at small scale.
- You're doing it because a blog post told you to. "Netflix does it" is not a reason. Netflix also has hundreds of engineers dedicated purely to infrastructure.
- Your domain boundaries aren't clear yet. Splitting services before you understand your domain just means you'll be doing painful cross-service refactors instead of easy in-process ones.
- You don't have strong DevOps or observability maturity. Without good tracing, centralized logging, and CI/CD discipline, microservices turn debugging into archaeology.
The Middle Path Nobody Talks About
The best-kept secret in backend architecture is the "modular monolith": a single deployable with strict internal module boundaries, clean interfaces, and no shared mutable state between modules. You get most of the organizational clarity of microservices (clear ownership, enforced boundaries) without the operational tax of a distributed system.
A lot of teams that eventually split into microservices would have been better served spending that time enforcing better boundaries inside their monolith first. And when you do eventually split, the modules practically become services on their own. The hard design work is already done by then.
A Simple Litmus Test
Before splitting a service, ask yourself: "What operational problem, specifically, would this solve that I cannot solve by refactoring inside my current deployable?" If the honest answer is "none, but it feels more scalable," you're not ready. If the answer is a specific, painful, recurring problem, like a team blocked on deploys, a service that needs to scale independently, or a failure domain that keeps taking down unrelated features, you probably are.
The Bottom Line
Microservices are a tool for organizational and operational scaling problems, not a badge of engineering maturity. The best architecture is the one that matches your team's size, your domain's boundaries, and your actual pain points, not the one that looks best on a conference slide. Sometimes that's microservices. Often, especially early on, it's a well-organized monolith that lets you move fast without paying rent to a service mesh.
