The industry has spent a decade telling you that microservices are the answer. For most companies, they are the answer to a question nobody asked. Here is what 19 years of building both architectures has taught us.
The Monolith Is Not the Problem
Shopify runs on a monolith. It handles billions of dollars in transactions. Stack Overflow serves 100 million monthly visitors from a monolith on a handful of servers. Basecamp has operated profitably as a monolith for 20 years.
The monolith did not fail these companies. It also will not fail yours — unless you have very specific problems that microservices solve.
When Microservices Actually Make Sense
You have 50+ engineers. The primary benefit of microservices is organizational, not technical. They allow multiple teams to deploy independently without stepping on each other. If you have one team of 8 developers, microservices add complexity without adding independence.
You have genuinely different scaling requirements. Your search service needs 100x the compute of your user profile service. Scaling them independently saves real money. But if your entire app scales uniformly, a monolith behind a load balancer works fine.
You need polyglot technology. Your ML pipeline is Python. Your real-time API is Go. Your data processing is Spark. Microservices let each service use the right tool. But if your entire stack is Node.js, you are adding network hops for no reason.
The Hidden Costs Nobody Mentions
Distributed debugging: A user reports an error. In a monolith, you grep one log file. In microservices, the request touched 12 services. You need distributed tracing (Jaeger, Zipkin), centralized logging (ELK, Datadog), and service mesh observability. This infrastructure costs $50K-200K/year before you solve a single bug.
Data consistency: In a monolith, you use database transactions. In microservices, each service has its own database. Now you need sagas, eventual consistency patterns, compensating transactions, and idempotency keys. Every distributed system bug is a data consistency bug.
Deployment complexity: One monolith = one deployment pipeline. Twelve microservices = twelve pipelines, twelve Docker images, twelve health checks, twelve scaling policies, twelve sets of environment variables. Your DevOps team just tripled.
The Right Approach
Start with a well-structured monolith. Clean module boundaries, clear interfaces between domains, dependency injection, and a solid test suite. This is a "modular monolith" — and it gives you 80% of the organizational benefits of microservices with 20% of the complexity.
Extract services only when you feel pain. When a specific module needs independent scaling, independent deployment, or a different technology — extract that one module into a service. This is surgical, not ideological.
We have helped clients migrate from monolith to microservices when they genuinely needed it. We have also helped clients migrate back from microservices to a modular monolith when the complexity was killing their velocity. Both moves increased their shipping speed by 3x.
Architecture is not religion. It is engineering. Make the choice that solves your actual problems.