I've built both. Multiple times. At startups with 3 engineers and at companies with 300. The internet is full of opinions on this debate, and most of them are wrong — or at least incomplete.
Here's what I've learned the hard way.
The Monolith Isn't the Enemy
A monolith is a single deployable unit. All your code lives together, shares a database, and deploys as one thing. The industry spent the last decade treating this like a design flaw. It's not.
Monoliths are simple to develop, simple to test, simple to deploy, and simple to debug. When something breaks at 3 AM, you grep one codebase, check one set of logs, and trace one request path. That simplicity has real value that gets dismissed too easily.
Shopify runs a monolith. So does Stack Overflow (serving millions of requests on remarkably modest hardware). These aren't companies that lack engineering talent — they made a deliberate architectural choice.
The Microservices Promise (And the Hidden Costs)
Microservices split your application into independently deployable services, each owning its own data and communicating over the network. The pitch sounds great: independent scaling, technology freedom, isolated deployments, team autonomy.
Here's what the conference talks skip:
Network complexity. Every function call that used to be in-memory is now an HTTP request or message queue. Latency increases. Failure modes multiply. You need circuit breakers, retries, timeouts, and distributed tracing just to understand what's happening.
Data consistency. No more database transactions spanning your entire domain. You're doing eventual consistency now, which means writing saga patterns, compensation logic, and accepting that your data will be temporarily wrong sometimes.
Operational overhead. A modular monolith needs 1-2 ops engineers. An equivalent microservices setup typically needs 2-4 platform engineers plus operational burden distributed across product teams. That's not free.
Testing complexity. Unit tests are fine. Integration tests? You need to spin up multiple services, mock external dependencies, manage test data across databases. Contract testing helps but adds its own complexity.
When Microservices Genuinely Make Sense
Microservices aren't bad — they're expensive. They make sense when:
- Different parts of your system need to scale independently. If your video processing pipeline needs 50x the compute of your user profile service, running them as one unit wastes resources.
- Multiple teams need to deploy independently. If Team A's release is blocked by Team B's incomplete feature, microservices solve that friction.
- You need technology diversity. ML pipeline in Python, API gateway in Go, real-time system in Rust — microservices let each service use the right tool.
- Your organization is large enough. Below about 50 engineers, microservices usually create more coordination problems than they solve.
The Modular Monolith: The Answer Most Teams Skip
There's a middle ground that doesn't get enough attention. A modular monolith is a single deployable application with strict internal module boundaries. Each module owns its data, has a defined API, and could theoretically become a service later.
You get architectural clarity without network overhead. You get module independence without distributed systems complexity. You get a clear migration path if you do eventually need microservices.
In 2026, with everyone focused on cloud cost optimization and FinOps accountability, this approach is increasingly attractive. Why pay for Kubernetes orchestration, service mesh networking, and distributed tracing when a well-structured monolith handles your actual load just fine?
A Simple Decision Framework
Team size under 20? Start with a modular monolith. You don't have the people to operate microservices properly.
Team size 20-50? Consider extracting specific services where you have clear scaling or deployment bottlenecks. Keep the rest monolithic.
Team size 50+? Microservices start making organizational sense. Conway's Law is real — your architecture will mirror your team structure whether you plan for it or not.
Regardless of size: If you're not experiencing a specific problem that microservices solve, you don't need microservices. Architecture should solve real problems, not theoretical ones.
The Real Trade-Off
This debate isn't actually about technology. It's about what kind of complexity you're willing to manage.
Monoliths have code complexity — large codebases, tangled dependencies, merge conflicts. These are familiar problems with familiar solutions.
Microservices have operational complexity — network failures, distributed debugging, deployment orchestration. These require specialized skills and expensive tooling.
Pick the complexity your team is equipped to handle. That's the whole decision.
Most teams would be better served by a well-organized monolith than a poorly-operated microservices architecture. The best architecture is the one your team can actually maintain at 3 AM when production is down.
Top comments (0)