The Architecture Decision Everyone Gets Wrong
“We need microservices.” Every startup CTO says it. Usually about six months before they regret it.
According to a 2025 CNCF survey, 42% of organizations that adopted microservices are now consolidating services back into larger deployable units. Not because microservices are bad. Because they used them when they didn’t need to.
Amazon Prime Video moved from distributed microservices to a single-process monolith and cut infrastructure costs by 90%. Twilio Segment collapsed 140+ microservices into one monolith after three full-time engineers spent most of their time firefighting instead of building features.
The pattern is clear. Teams adopt microservices for the wrong reasons, pay the complexity tax for years, then simplify. Don’t be that team.
What Microservices Actually Cost
The infrastructure alone runs 3.75x to 6x higher than a monolith for equivalent functionality. That’s before counting the human cost.
Each service needs its own deployment pipeline, monitoring, logging, and alerting. Service-to-service communication needs to handle network failures, retries, timeouts, and circuit breaking. Data consistency across services requires distributed transaction patterns or eventual consistency (and the bugs that come with it).
A monolith needs one deployment pipeline. One monitoring setup. One database. One team that understands the whole system.
For small and medium teams, microservices reduce feature delivery speed by 20-40% despite promises of independent deployment. The overhead is real. A modular monolith needs 1-2 operations-focused engineers. An equivalent microservices architecture needs 2-4 platform engineers plus distributed operational burden.
Sound like a good trade for a 15-person company? It’s not.
When Monoliths Win (Which Is Most of the Time)
You’re still figuring out your product. Domain uncertainty favors monoliths. When you’re still discovering what your application needs to do and how different features relate, the flexibility to refactor across boundaries is priceless.
Your team is under 30 engineers. The coordination overhead of microservices only pays off when you have enough people that a single codebase creates merge conflicts and deployment bottlenecks.
Your application handles under 1 million requests per day. Below that threshold, a well-optimized monolith handles everything without breaking a sweat. Most SMB applications never come close to this number.
You don’t have a dedicated platform or infrastructure team. Microservices without platform expertise means every developer becomes a part-time SRE. Features slow down.
The Modular Monolith: The Answer Nobody Talks About
Here’s the architecture that most teams actually need.
A modular monolith is a single deployable application with clear internal boundaries. Each module owns its domain (users, orders, payments, inventory). Modules communicate through well-defined interfaces, not direct database queries across domains.
You get the separation of concerns that microservices promise without the operational overhead. And when (if) a module genuinely needs to be extracted into a separate service, the boundaries are already clean. The extraction is straightforward instead of surgical.
Rails, Django, and NestJS all support modular monolith architecture natively. Organize your code into domain modules. Define interfaces between them.
Keep them in one repo, one deployment, one database (with separate schemas if you want extra isolation).
The key discipline: modules don’t reach into each other’s database tables. They call each other through defined interfaces. This single rule prevents the coupling that makes monoliths messy.
When Microservices Actually Make Sense
They’re not useless. They solve real problems at specific scales.
Multiple autonomous teams working on different business domains. When you have 50+ engineers and 8+ teams, independent deployment becomes genuinely valuable. Each team owns their services end-to-end.
A component needs independent scaling. Your search service handles 10x the traffic of your user management service. Scaling them independently saves money versus scaling the entire monolith.
Technology heterogeneity is required. Your ML pipeline needs Python. Your real-time messaging needs Go. Your web backend runs TypeScript.
Different services in different languages makes sense when the requirements genuinely differ.
Fault isolation is critical. A bug in the recommendation engine shouldn’t crash the checkout process. Service boundaries provide natural blast radius containment.
If none of these apply to you, you don’t need microservices. You need a well-structured monolith.
The Migration Path: Monolith to Microservices (When the Time Comes)
Start with a modular monolith. Build features. Find product-market fit. Grow your team.
When a specific module becomes a bottleneck (it needs to scale independently, or it’s blocking other teams, or it has fundamentally different operational requirements), extract it.
This is the strangler fig pattern applied to architecture evolution. The monolith gradually loses modules to independent services.
But only the modules that genuinely benefit from extraction.
For most companies, you’ll extract 2-5 services over the life of the application. Not 140. The rest stays in the monolith, and that’s fine.
If you’re dealing with a legacy monolith that’s become unmanageable, our legacy modernization guide covers the extraction patterns. And for the broader context of making technology decisions that support your business growth, read our digital transformation playbook.
The right architecture isn’t the most sophisticated one. It’s the one that lets your team ship features and iterate on your product. For most teams, most of the time, that’s a modular monolith.
Save the microservices for when you’ve outgrown it. You’ll know when that day comes, because the symptoms will be technical debt you can no longer ignore.
Debating your architecture? Let’s talk through the trade-offs for your specific situation. We’ll look at your team size, your product stage, and your growth trajectory, then recommend the architecture that actually fits.