The Modular Monolith Comeback: Why Teams Are Reversing Microservices Decisions
Amazon Prime Video cut costs 90% by merging a distributed pipeline back into one process, and Segment did the same to 140+ services in 2018 โ the real lesson isn't that microservices are wrong, it's about when the network hop actually pays for itself.
Written from the perspective of a software architect who has to sign off on service-boundary and deployment-topology decisions before a team commits months of build time to them, where the cost of an early wrong split shows up in infrastructure and on-call budgets long before anyone calls it an architecture review.
Teams that split into microservices early are re-consolidating: Amazon Prime Video cut infrastructure costs 90% by merging a distributed service into one process, and Segment folded 140+ microservices back into one codebase after overhead outpaced the benefit. Neither case is a verdict against microservices; both are about boundaries drawn before a domain had stabilized, costing more than they saved.
1. The Backlash Is Real, and It Has Real Numbers Behind It
Two case studies get cited constantly in this conversation, and both hold up under scrutiny.
Segment's engineering team wrote the more detailed one in 2018: after growing to over 140 microservices, they found three full-time engineers spending most of their time just keeping the system alive, with shared-library versions diverging across the fleet and each service's distinct CPU/memory profile turning autoscaling into what author Alexandra Noonan called "more art than science." They merged the fleet back into a single monolith. The result they measured directly: 32 shared-library improvements in the last full year running microservices, versus 46 in the six months after the merge.
Amazon Prime Video's 2023 case is more specific and more often misquoted. The Video Quality Analysis team's original distributed pipeline, AWS Step Functions orchestrating Lambda functions that passed video frames through S3, hit a hard scaling limit at around 5% of expected load. Consolidating the pipeline into a single process running on Amazon ECS cut infrastructure cost by 90%. What most retellings drop, and what The Stack's contemporaneous coverage was careful to note: Prime Video didn't abandon microservices as a company. One team restructured one service; the rest of Prime Video's architecture stayed distributed. The headline number is real. The "microservices are dead" framing built on top of it isn't what happened.
2. Why Boundaries Drawn Early Cost More Than They Save
Martin Fowler named this pattern back in 2015, well before either case study above existed, in an article called "MonolithFirst": "You shouldn't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile." His argument isn't that microservices are bad. It's that drawing service boundaries requires knowing where a domain's natural seams actually are, and that knowledge doesn't exist on day one of a project. "Most systems acquire too many dependencies between their modules, and thus can't be sensibly broken apart" once boundaries are guessed wrong early and code grows around the guess.
There's also a fixed cost Fowler calls the microservices premium: network calls where a function call used to be, distributed transactions where a database transaction used to be, per-service deployment pipelines, per-service on-call burden, and cross-service debugging that used to be a single stack trace. None of that cost is optional once a system is distributed, and none of it buys anything until the system is big enough, or the team is split across enough independent groups, that the coordination cost of a single codebase would have been worse. Segment's numbers are what that premium looks like paid by a team that wasn't yet at that size: three engineers' full-time output going to keep 140 services alive, instead of into the product.
3. What a Modular Monolith Actually Trades Away, and What It Keeps
A modular monolith is a specific architecture, not just "microservices, abandoned." It runs and deploys as a single unit, but internally it's organized into modules with enforced boundaries: each module owns its own tables (or its own subset of a schema), talks to other modules only through explicit interfaces, and is forbidden from importing another module's internals directly, usually by a build-time or lint-time dependency rule. The goal is to keep the organizational benefit microservices were chasing in the first place, clear ownership, one team's changes can't silently break another module's invariants, while dropping the specific costs that don't earn their keep at a given team size: no network hop for an in-process call, no distributed transaction where a database transaction still works, one deployment pipeline instead of many, one process to instrument and debug instead of a call graph spanning several services.
The honest tradeoff: a modular monolith still deploys as one unit, so a bug in one module can still take down a build for everyone, and there's no way to give one module a different scaling profile or a different runtime than the rest, short of extracting it. That extraction is exactly what a modular monolith is supposed to make cheap when the day comes, because the module boundary already exists in code before it needs to exist on the network.
4. When Microservices Are Still the Right Call
None of the above is an argument that microservices are always wrong, and swinging to "always start with a monolith" as dogma would be the same category of mistake as swinging to "always start with microservices" was a decade ago. A few signals are worth taking seriously as a case for splitting a service out, on their own or in combination.
| Signal | Why it justifies the network hop |
|---|---|
| Independent deploy cadence | A team genuinely needs to ship on its own schedule without coordinating a release train with other teams, and the coordination cost is measured, not assumed |
| Divergent scaling profile | One workload is bursty and CPU-bound while the rest of the system is steady-state and I/O-bound, so scaling them together wastes real money |
| Org-boundary ownership | Conway's Law is descriptive, not aspirational, but when two teams already run separate on-call, separate roadmaps, and separate data-access needs, a shared codebase is fighting the org chart instead of matching it |
| Regulatory or data-isolation boundary | A workload has a genuinely different compliance or access-control boundary (PCI scope, PII handling) that's cheaper to enforce as a separate deployable with its own audit trail |
The failure mode the Segment and Prime Video cases both describe isn't "microservices are wrong." It's paying the microservices premium before any of these signals were true yet, on the assumption that they eventually would be.
5. A Decision Checklist Before You Split a Service Out
Translating the above into a decision that holds up under a real roadmap review:
- Start new projects and new domains as a modular monolith, with module boundaries enforced by tooling (dependency-cruiser, ArchUnit, or your language's equivalent), not by convention alone. Convention erodes under deadline pressure; a build-time rule doesn't.
- Don't extract a service because the org chart changed. Extract it because a specific, measured signal from the table above is already true, not because it might be true in a year.
- If the reason to extract is deploy cadence, measure the actual coordination cost first. A release train that adds one day of latency to a deploy is not the same problem as one that blocks a team for a sprint.
- When you do extract, follow the module boundary you already enforced in code, not a new boundary discovered mid-migration. That's the entire value of doing the modular part first.
- Budget for the ongoing cost of a split honestly: on-call rotation, a separate deployment pipeline, cross-service debugging tooling, and, per Segment's numbers, real engineering time that will not go into the product. If that cost doesn't have a name and a number attached before the split, it will show up anyway, just unplanned.
Frequently Asked Questions
Does the modular monolith trend mean microservices were a mistake?
No. The most-cited case studies make a narrower point than the headlines suggest: Amazon Prime Video didn't abandon microservices as a company โ one team consolidated one distributed pipeline into a single process and cut its cost by 90%, while the rest of Prime Video's architecture stayed distributed. Segment's team merged 140+ services back into one codebase, but that was a response to being under-resourced for the operational cost of that many services, not a verdict that service-oriented architecture is inherently wrong. The pattern is about paying a real cost (the 'microservices premium') before the boundaries or the team size justified it, not about microservices being a bad idea in general.
What is a modular monolith, exactly?
A modular monolith deploys and runs as a single unit but is organized internally into modules with enforced boundaries: each module owns its own data, communicates with other modules only through explicit interfaces, and is prevented, usually by a build-time or lint-time rule, from reaching into another module's internals directly. It keeps the ownership clarity microservices are meant to provide while dropping the network hop, the distributed transaction, and the per-service deployment pipeline until a specific, measured reason to extract a service shows up.
When does it actually make sense to split a monolith into microservices?
When at least one concrete signal is already true, not anticipated: a team needs an independent deploy cadence and the coordination cost of a shared release train is measured and real; a workload's scaling profile genuinely diverges from the rest of the system (bursty and CPU-bound versus steady-state and I/O-bound); the team boundary and the codebase boundary are fighting each other (Conway's Law); or a workload has a distinct regulatory or data-isolation requirement that's cheaper to enforce as a separate deployable. Martin Fowler's MonolithFirst argument is that these boundaries are hard to identify correctly before a system has had time to reveal where its natural seams actually are.