ML
Microservices

The Distributed Monolith: How Microservices Quietly Go Wrong

You split the monolith into ten services and somehow got slower, more fragile, and harder to deploy. That's a distributed monolith — the worst of both worlds. Here's how to spot and avoid it.

May 27, 202610 min readMicroservicesSystem Design

The promise of microservices is independent deployability: each team ships its service on its own schedule. The failure mode that eats that promise is the distributed monolith — services that are physically separate but so tightly coupled they must be built, tested, and deployed together. You paid the network tax and kept the coupling.

1. The symptoms

  • Changing one service forces a coordinated release of three others.
  • A single user action fans out into a chain of synchronous calls; if any hop is down, the whole thing fails.
  • Services share a database, so a schema change ripples everywhere.
  • You can't test a service without spinning up half the system.

2. Shared database is the original sin

If two services read and write the same tables, they are one service wearing two hats. The schema becomes a public API nobody owns, and every migration is a cross-team negotiation. Each service must own its data and expose it only through its API or events — no reaching into another service's tables.

3. Synchronous chains multiply failure

A request that hops A→B→C→D synchronously has availability 0.99⁴ ≈ 96% even if every service is 99% up, and its latency is the sum of the chain. Break the chain: make non-critical work asynchronous via events, and collapse chatty call sequences so one service doesn't orchestrate five others on the hot path.

A → B → C → D     // 4 hops: latency adds up, failure compounds
A emits event → B, C, D react independently   // decoupled, resilient

4. Boundaries follow the domain, not the org chart

Draw service boundaries around business capabilities that change together (a bounded context), not around technical layers or whoever happened to write the code. A boundary that needs constant cross-service transactions is in the wrong place — that data wants to live together.

5. Version contracts; don't break them in lockstep

Independent deploy requires backward-compatible contracts. Add fields, don't repurpose them; support old and new for a deprecation window. The day a producer change requires every consumer to redeploy simultaneously is the day you've rebuilt the monolith over HTTP.

Rules of thumb

  • One service owns its data. No shared tables, ever.
  • Default to async events; reserve synchronous calls for genuinely interactive paths.
  • Boundaries around bounded contexts, not layers or teams.
  • If a change forces a lockstep multi-service deploy, your boundaries or your contracts are wrong.
  • Don't start with microservices. Extract them from a monolith once the seams are obvious.
SharePostLinkedIn

Reader Discussion

1 replies// weighed in

TopNewestAuthor
Add to the thread
Disagree, agree harder, or share your own experience…
Email instead →markdown okbe kind
  1. Léa Dubois· SREAsks

    any chance you'd publish these as a PDF collection? would love to print and read offline on flights. screen-fatigue is real.

    Jun 02, 2026·6 days later

Worked on something similar? Email ducminhldm@gmail.com — I read every one. The good ones become future posts.

Comments seeded · live discussion via email