The Case Against Microservices
Before you break apart your monolith, understand the hidden costs, perverse incentives, and cultural traps of the microservice architecture.
For the last few decades, the microservice architecture has been presented as the pinnacle of software engineering, at least on the backend. Everyone wants one, or better yet, a hundred. Popularized by now-trillion-dollar corporations and incentivized by promotion packet requirements, it has become a high bar that every engineer is pressured to reach.
To this day, not many people can build them effectively. Those who can, bring millions, sometimes billions, to their employers. But do they? I’m going to build a case against microservices for most companies. This case is against their premature and often dogmatic adoption in the startups and small-to-medium companies where most of us work.
The Seductive Case for Microservices
When you ask why a team chose microservices, a typical answer is “scale.” What scale? How was it measured?
Chances are, there are quicker and cheaper ways of achieving scale than rewriting everything into a distributed system. History is filled with examples of massive scale being handled by monoliths. For years, Stack Overflow served enormous traffic on a handful of monolithic servers. A single executable on a modest cloud instance can often handle the entire user load of a well-funded startup through its first five to ten years of growth. The bottleneck is almost always the database, not the application architecture.
Getting that monolith from 0.5 to 500 requests per second might be a week-long project involving some query optimization and caching, and costing a few thousand dollars a month in larger servers and a Redis instance. Building a distributed system to handle that same load is a six-month-to-multi-year, multi-engineer project with a five-figure monthly operational cost. If your default choice is a distributed system, you’re likely doing it wrong.
The more sophisticated arguments for microservices are about organizational scale, not raw traffic. Proponents will point to more nuanced benefits, such as independent deployability, fault isolation, and clear ownership.
These are valid arguments in the right context. For the $100 billion corporations they came from, they are essential. For most companies, they are a trap.
Deployability: the cognitive overhead of managing multiple deployment pipelines, monitoring dashboards, and contracts between services is a net loss in velocity compared to a well-structured monolith.
Fault Isolation: you gain more resilience from simplicity. A distributed system introduces many more points of failure: network latency, service discovery, and contract mismatches.
Ownership: a modular monolith can have equally clear ownership boundaries. The principles of Domain-Driven Design, like Bounded Contexts, are not exclusive to microservices. You can design the monolith as a set of well-defined modules (e.g., `
src/checkout/`, `src/recommendations/`) that communicate through clear internal APIs.
The Real Drivers: Incentives and Intellectual Curiosity
“Show me the incentives and I will show you the outcome.”
— Charlie Munger
If the technical arguments are so often misguided, why are microservices everywhere?
I won’t pretend to know how it all started. I don’t know how it crept into every big and small company, or how startups with no paying customers end up with multiple executables talking to each other over the network just to respond to a single user request. But the current situation is clear: the requirements for getting hired and promoted often demand experience with distributed systems.
On one of my own system design interviews, I elaborated on why the company in question had no need for a distributed system. Between the three of us in the room, I had the most knowledge and hands-on experience managing more traffic per day than the company had handled since its inception. Naturally, it wasn’t a good fit.
This pressure to build complex systems is an open secret.
If your company’s promotion packet requires “scale” or “complexity” to prove your worth as an engineer, the entire software stack will inevitably become overengineered. In turn, the people who get promoted in such a system will defend the status quo and hoard tribal knowledge of how it all works. They become merchants of complexity because the success of their careers depends on it.
For some, it’s also a status symbol. Some companies present a complex distributed system architecture at engineering conferences while quietly running a monolith, all presumably to attract the “best and brightest.”
Finally, there is the need for intellectual stimulation. Great engineers have been grinding knowledge like their lives depended on it for as long as they can remember. At some point, the technical learning curve flattens. The realization hits: “You’re going to do the same thing 5 days a week for the next 50 years.” The adventure on a pirate ship, robbing kings and singing shanties, has become a navy. And you’re the lowest-ranking deck-cleaner on a predictable route. The complexity of a distributed system provides a welcome challenge.
Pragmatism Over Dogma: When to Actually Consider a Distributed System
The argument here isn’t “never use microservices.” It’s “don’t start with them, and migrate only when you have to.”
The list of compelling reasons to choose a distributed architecture is incredibly short. It typically boils down to four scenarios:
Extreme Team Friction: teams are stepping on each other’s toes so badly that it has become the number one blocker to shipping anything.
Different Technical Needs: you have a part of the system with a workload so unique it requires a completely different tech stack.
Disproportionate Resource Needs: one part of your system requires a completely different scaling profile or hardware from the rest of your CRUD app.
Extreme Fault-Tolerance Requirement: the failure of one non-critical component must be prevented from ever causing an outage in the critical path.
The Solution: Change the Incentives
You can’t just tell smart people not to be smart. You have to give them better problems to solve.
For Founders & CTOs
This culture starts with your hires. Select for pragmatists who are not obsessed with tech stacks. And when it comes time to define career ladders, reward real impact. Stop rewarding complexity and start rewarding value.
Instead of “designed and launched 5 new microservices”, try “reduced dashboard page latency by 500ms, increasing user engagement by 12%.”
Instead of “led the migration from a monolithic to a microservices architecture”, try “deleted 10K lines of legacy code and reduced the monthly cloud bill by $15K, with zero downtime.”
Make the hero of the story the person who delivers impact, not the one who adds the most boxes to the architecture diagram.
For Team Leads & Managers
You have the power to create a sub-culture of simplicity. Define project success by customer outcomes, not architectural buzzwords. Celebrate the engineer who prevents an outage by deleting dead code with the same energy as the one who ships a new service.
You can’t suppress an engineer’s need for a challenge, but you can redirect it. Instead of building complex plumbing, focus on harder, more valuable problems. For example:
Go deep on performance.
Master the domain.
Build better tools.
Innovate on the product.
For Individual Engineers
You can fight this. Frame your contributions in terms of business impact. When you refactor and remove 5K lines of code, document the resulting latency reduction or cost savings. Make simplicity’s value visible and celebrate it. When you propose a solution, present the simplest version first.
The ultimate solution is to create a culture where the most respected engineers are not the merchants of complexity, but those who build effective solutions that help the business win.




