Microservices were designed to solve a specific problem: too many engineers trying to change one codebase at the same time. That is an organisational constraint, not a technical one.
If you have eight engineers, you do not have that problem. You will still get every cost that microservices carry, and none of the benefit.
What you are actually choosing between
A monolith is one deployable application. One repository, one database usually, one deployment. Everything calls everything else directly as function calls.
Microservices are many small applications, each deployable on its own, each typically owning its own data, communicating over the network.
The trade is simplicity for independence. You are buying the ability for teams to ship without coordinating, and paying for it with distributed systems problems.
What microservices actually cost
These costs are real, universal, and consistently underestimated.
- Every function call becomes a network call. Which means it can be slow, fail, time out, or arrive twice. Code that was three lines becomes thirty with retries and error handling.
- Debugging becomes archaeology. A single user action touches six services. Finding what went wrong requires distributed tracing, which is infrastructure you now have to run.
- Data consistency goes from free to hard. In a monolith a transaction either commits or it does not. Across services you are writing compensating logic by hand.
- Deployment complexity multiplies. Twelve services means twelve pipelines, twelve sets of configuration, and version compatibility between them.
- You need real infrastructure skill. Service discovery, orchestration, centralised logging, monitoring. See our note on the DevOps career path for what that role involves, because you will need one.
- Local development gets painful. A new developer needs to run eight services to change one screen.
When microservices are genuinely right
Four signals. You need at least two of them before splitting is a good idea.
1. Team size and coordination cost
More than roughly thirty engineers on one codebase, where merge conflicts and release coordination are visibly slowing people down. This is the original problem and the strongest signal.
2. Genuinely different scaling profiles
One part of the system needs ten times the capacity of the rest. Video processing, search, report generation. Splitting that out so you can scale it independently is a sound reason.
3. Genuinely different technology needs
The machine learning component belongs in Python and the rest is .NET. A real reason, and a smaller one than it sounds, because you can often solve it with one separate service rather than twenty.
4. Different reliability requirements
Payments must stay up when the recommendation engine falls over. Isolation has genuine value here.
Notice what is not on this list: “it is modern”, “large companies do it”, “we might scale one day”. None of those are reasons.
The answer for most teams: a modular monolith
This is the option nobody advertises and most teams should choose.
One deployable application, but internally organised into clear modules with defined boundaries. Orders does not reach into the Inventory tables directly; it calls an Inventory interface. Same discipline as microservices, without the network.
You get: one deployment, simple debugging, real transactions, easy local setup. And when you genuinely need to split something out later, the boundary already exists and the extraction is straightforward.
Almost every successful microservices migration started as a well structured monolith. Almost every failed one started as microservices on day one.
How to split later, when you actually need to
- Split by business capability, not by technical layer. An Orders service is right. A Database service is wrong.
- Start with the piece that has a real reason. The part that scales differently, or the part one team wants to own outright.
- Extract one service and live with it for a quarter. You will learn what infrastructure you are missing before you have twelve of them.
- Give each service its own data. Services sharing a database are a monolith with extra network latency and none of the benefits.
- Invest in observability before the second split, not after the sixth.
The question worth asking your development partner
“How many engineers will be working on this in a year, and which part of it has a different scaling profile?” If neither answer suggests a split, and they are still proposing microservices, they are building for their CV rather than your business.
Related reading: how to scale a web application and migrating a legacy system without downtime.
Frequently asked questions
Are microservices better than a monolith?
Neither is better in general. Microservices solve coordination problems for large teams at the cost of operational complexity. Below about thirty engineers, a well structured monolith usually wins.
Can a monolith scale?
Yes, considerably further than most people assume. Horizontal scaling behind a load balancer, caching and database tuning take a monolith a very long way. Scale is rarely the reason to split.
What is a modular monolith?
A single deployable application organised into modules with enforced boundaries and no direct cross module data access. It gives you most of the design discipline of microservices without the distributed systems cost.
We already have microservices and it is painful. What now?
Merging services back together is a normal and often correct decision. Start with the ones that always deploy together and always change together, because those were never separate concerns.
Ezitech has designed and rebuilt platforms for clients across 42 countries and will tell you plainly when a simpler architecture serves you better. Describe what you are building.
