Skip to content
José da Cruz

Enterprise Architect, and Life Thinker

José da Cruz

Enterprise Architect, and Life Thinker

The Distributed Monolith: When Your Microservices Still Deploy as One App

josedacruz, August 18, 2026August 18, 2026

TL;DR: Splitting a monolith into microservices doesn’t automatically get you the benefits people promise — independent deploys, one team’s mistake not taking down everyone else, services that scale on their own. If your new services still call each other synchronously, share a database, or all have to deploy together, you’ve built a “distributed monolith”: all the network overhead of microservices with none of the decoupling. This post walks through what actually matters when deciding whether to split a service, and how to tell if you’ve already landed in the trap.

Picture a team at an online store called ShopFast. Their old system was one big Java application: order handling, inventory, and payments all lived in the same codebase, talked to each other through plain function calls, and deployed together every Friday. It worked, but it was slow to change — one team’s bug in the payments code could block a release for the whole app.

So they did what a lot of teams do. They split it into three services: Order Service, Inventory Service, and Payment Service, each with its own repository and its own deploy pipeline. Six months later, someone points out that they still can’t deploy Inventory Service without also deploying Order Service, because the two are joined at the hip by a shared database table and a chain of synchronous calls. They have three codebases now, and all the same problems they had before — plus network latency and three times the operational work. They built a distributed monolith.

What actually matters here

Before deciding whether to split a service (or trying to figure out if you already made a mistake splitting one), it helps to have a short checklist. A split only pays off if you can answer “yes” to most of these:

  • Can this service deploy on its own? If deploying Inventory Service always requires deploying Order Service in the same window, they are not really separate services — they are one thing pretending to be two.
  • Does it own its data? If two services read and write the same database tables, a schema change in one can silently break the other. That is coupling, even though it’s hidden behind a network boundary.
  • Can it fail without taking others down with it? A real microservice split gives you fault isolation: Payment Service having a bad day shouldn’t mean nobody can browse the product catalog.
  • Is most of the communication asynchronous, or at least optional? A web of synchronous, “must succeed right now” calls between services recreates the tight coupling of a single process, just slower and less reliable.

If the honest answer to most of those is “no,” you don’t have microservices in any meaningful sense. You have a monolith that happens to run as several processes talking over HTTP.

Quadrant chart plotting coupling against deploy independence, showing old monolith, distributed monolith, modular monolith, and well-split services in each quadrant
The “distributed monolith” quadrant is the trap: loosely coupled in name, but still forced to deploy together.

How ShopFast ended up there

Nobody at ShopFast decided to build a distributed monolith on purpose. It happened one reasonable-looking decision at a time.

First, they kept a single shared database “for now,” because migrating data was going to take extra sprints and the deadline was close. Then, when Order Service needed to know if an item was in stock, the fastest way to build it was a direct, synchronous call to Inventory Service and a wait for the answer. Same thing for charging the customer’s card: a direct call to Payment Service, block until it responds. Nobody sat down and asked “should these three services really need to succeed together, in order, every single time?” It just happened, request by request.

Sequence diagram showing the web app calling Order Service, which synchronously calls Inventory Service and Payment Service in turn before responding
One customer order now depends on four services all being healthy, in a chain, at the same moment.

This is the trap: each individual call felt like the simplest way to get the feature working. But stack enough synchronous calls together and you’ve rebuilt the exact thing you were trying to escape — one slow or broken part stops the whole flow, except now every step also has network latency, retries, and timeouts to think about. A bug in a shared library used to be a compile error. Now it’s a 2am page about “intermittent order failures” that takes an hour to trace across three services’ logs.

Monolith, microservices, or this — what’s the actual trade-off

It helps to be honest about what each option really buys you, instead of assuming “microservices” is automatically the upgrade.

A well-built monolith is simple to run, has no network calls between its internal parts, and is very fast, because everything happens in one process. Its downside is that everyone deploys together and a bug anywhere can affect everything — that’s the coupling problem ShopFast started with.

Well-split microservices trade some of that simplicity and speed for independence: teams can deploy on their own schedule, and a failure in one service doesn’t have to sink the others. That trade only pays off if the split is real — separate data, mostly async communication, genuine fault isolation. You are choosing to pay a latency and operational tax in exchange for organizational independence.

A distributed monolith is the worst of both: you pay the network latency and operational tax of microservices, but you still get the coupled deploys and cascading failures of a monolith, because the boundaries were never truly independent. You paid for the upgrade and didn’t get it.

Mindmap listing four signs of a distributed monolith: deploys together, talks synchronously, shares a database, fails together
If most of these branches sound familiar, the split happened on paper more than in practice.

Notice that “modular monolith” — one deployable process, but with clean internal boundaries and no shared mutable state between modules — is often a better stepping stone than jumping straight to network calls. You get most of the coupling discipline without paying for the network hop, and you can split a genuinely independent module out later once it’s proven it doesn’t need the others in lockstep.

The rule of thumb

Before you split a service, or before you defend a split you already made, ask one question: if this service’s database and its deploy pipeline had to be 100% independent starting tomorrow, would anything break? If the honest answer is “yes, a lot would break,” you don’t have a service boundary yet — you have a network call standing in for a function call, and you should either finish the split properly (separate data, async communication where possible, real ownership) or merge the pieces back into one deployable unit until you’re ready to do it right.

Splitting a system is not free, and it is not automatically progress. It’s worth it exactly when it buys you real independence. Anything less is just a more expensive way to run the same monolith.

Related

architecture architecture anti-patternsdistributed monolithmicroservicesservice boundariessystem design

Post navigation

Previous post
Next post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • architecture (154)
  • artificial-intelligence (6)
  • books (2)
  • courses (4)
  • decision-frameworks (4)
  • finances (1)
  • java (8)
  • life-improvement (20)
  • metrics (3)
  • observability (2)
  • puzzles and challenges (3)
  • reviews (1)
  • security (8)
  • spring-boot (36)
  • Systems Thinking (3)
  • GitHub Weekly: MCP Tools Trending Right Now (September 28 – October 4, 2026)
  • The Bulkhead Pattern: Why One Slow Dependency Shouldn’t Sink the Whole Ship
  • Essential Reading: A Philosophy of Software Design — Fighting Complexity One Module at a Time
  • GitHub Weekly: Top 10 Trending Repos (September 21 – September 27, 2026)
  • The Volunteer Tax: Why Raising Your Hand in a Meeting Makes You the Permanent Owner
©2026 José da Cruz | WordPress Theme by SuperbThemes