Microservices were supposed to make systems easier to change. In many enterprises, they made them harder.
The promise is real and well known: independent deployability, technology flexibility, the ability to scale parts of a system on their own. The trap is equally real and less discussed. Past a certain point, service proliferation, tangled inter-service dependencies, scattered data, and observability gaps combine to produce a distributed system harder to develop, operate, and change than the monolith it replaced. The architecture meant to reduce complexity has instead relocated it, from inside one application to between hundreds of them, where it is far harder to see and to manage.
How the Trap Closes
The trap rarely announces itself. It closes gradually, one reasonable decision at a time. A monolith is decomposed into services, which works well at first. Then more services are added, because adding a service is easy and feels like good practice. Dependencies accumulate between them, because real systems are interconnected. Data spreads across service boundaries, because each service owns its own. And observability lags, because watching one application was simple and watching a constellation of ephemeral services is not.
No single step is wrong. The sum is a system where a change that touched one place in the monolith now ripples across a dozen services, where understanding the whole requires holding hundreds of moving parts in your head, and where an incident becomes a distributed investigation across components no one fully understands. The complexity did not disappear when the monolith was broken up. It moved into the spaces between the services, and multiplied.
A simple picture captures it. A monolith is one large house: everything is in one place, which has real drawbacks, but you always know where things are and moving between rooms is trivial. Microservices turn the house into a village of separate buildings. Each building is simpler on its own, but now everything that used to be a walk down a corridor is a trip across the village, in the weather, with the risk that a building you need is closed. The complexity of any single building fell. The complexity of living in the village rose, and for many enterprises it rose past anything the original house ever imposed.
The Symptoms of Distributed Systems Debt
There are recognisable signs that an architecture has crossed from beneficial microservices into accumulated distributed systems debt. Simple changes require coordinated deployments across multiple services, which is the independent deployability the architecture promised, inverted. A single user request fans out across so many services that understanding its behaviour means tracing it through all of them. Data consistency becomes a recurring source of bugs, because state that was once a single transaction is now spread across services with no shared transaction. And every incident becomes an exercise in correlation across systems, slow and expensive, because the failure is rarely where the symptom appears.
When these symptoms show up, the architecture is no longer delivering its promised benefits. It is accumulating debt, and the debt compounds, because each new service added to a system already past the trap makes the whole harder rather than easier.
The Root Cause Is the Boundary
The trap almost always traces back to how the service boundaries were drawn. The common mistake is to decompose technically, splitting the system along technical lines or simply into ever-smaller pieces, on the assumption that smaller services are inherently better. They are not. A service boundary drawn in the wrong place creates exactly the tight coupling microservices were meant to avoid, because the things that change together end up in different services and every change has to cross a boundary.
The alternative is to draw boundaries around domains, around the areas of the business that genuinely change independently, so each service owns a coherent piece of the business and the things that change together stay together. Boundaries drawn this way produce services that are genuinely independent, because the independence reflects a real division in the business rather than an arbitrary technical one. The number of services matters far less than where the lines between them fall.
A Diagnostic for Whether You Are in the Trap
A few questions reveal whether an architecture is delivering microservices benefits or accumulating distributed debt. Can a typical change be delivered by deploying a single service, or does it require coordinating several? Can a single team understand and own a service end to end, or does every change require consulting others? Is data ownership clean, or is consistency a recurring problem? And when an incident occurs, is the cause usually local to one service, or does diagnosis require tracing across many?
Honest answers locate the architecture on the spectrum between healthy microservices and distributed systems debt. An architecture that fails these questions does not need more services or better tooling. It needs its boundaries redrawn around domains, which is harder than adding another service and is the only thing that actually addresses the cause.
The Boundary Is the Whole Decision
Microservices deliver their promised benefits only when the boundaries are drawn around domains that genuinely change independently, and they create a complexity worse than the monolith when they are not. The number of services, the choice of technology, the sophistication of the tooling, all of it matters less than where the lines between services fall, because the boundary determines whether the architecture reduces complexity or merely relocates and multiplies it. Before adding the next service, the question worth asking is not whether the system should be more distributed, but whether the boundaries it already has are drawn around the business or around the code. The boundary is the whole decision. Everything else is detail.