In a microservices architecture, what is a 'distributed monolith', and what's usually the first symptom a team notices?
answer
- lockstep deploys
- shared DB = shared monolith
- network calls, monolith coupling
- worst of both worlds
- Segment's 2018-2020 consolidation
basics
~20 sIt's when you've split code into separate services but they're still so tightly tied together that you can't deploy or change one without touching the others - you get all the complexity of microservices with none of the independence.
solid answer
~30 sA distributed monolith is a system split into physically separate, network-connected services that nonetheless behave like a single monolith because of hidden coupling - shared databases, synchronous call chains, or a shared library/schema that forces coordinated releases. The classic tell is lockstep deployment: to ship a change, multiple teams must merge, test, and release their services together in a fixed order, because a change in one breaks contracts in another. You've paid for network latency, partial failures, and operational overhead, but gained none of the independent-deployability benefit that justified going to microservices in the first place.
go deeper
Should recognize the term and give the lockstep-deployment symptom as the headline sign; doesn't need to name root causes precisely.
Should name at least two concrete causes (shared DB, sync call chains) and connect them to the deployment symptom.
Should be able to diagnose it from real symptoms (release calendars, incident postmortems) and explain why it erases the ROI of the migration.
Should connect the anti-pattern to org design and migration strategy - e.g., how it commonly emerges from strangler-fig migrations stalled halfway, and how to prevent it up front via bounded-context-driven decomposition.
## What the term names A **distributed monolith** is a system decomposed into multiple physically separate deployables — separate processes, separate repositories, separate deploy pipelines — that communicate over a network, yet still cannot be changed, tested, or deployed independently because of coupling left over from (or introduced during) the split. The physical topology says 'microservices'; the runtime behavior says 'monolith.' Common causes include: - a **database shared** by several services - long chains of **synchronous blocking calls** between services - a **shared versioned client library** that embeds business logic and forces every consumer to upgrade together - **cross-service transactions** that must commit or roll back as a unit ## Why teams end up here This pattern exists because decomposing a system is hard, and it's much easier to physically move code into a new process than to properly separate the data and behavioral ownership behind it. Teams under delivery pressure often extract a module into its own service — new repo, new deploy pipeline, new Docker image — while leaving it pointed at the same shared database and the same synchronous call patterns it used as an in-process module. The org gets to say 'we did microservices' while the actual **coupling graph**, which is what determines whether teams can move independently, hasn't changed at all. ## The trade-off The trade-off is stark and almost entirely negative. - **True microservices** trade some complexity (network calls, eventual consistency, more infrastructure) for independent deployability, independent scaling, fault isolation, and the ability for different teams to choose different release cadences or even different tech stacks. - **A distributed monolith** pays the complexity cost — network latency on every call, partial failure modes, harder distributed debugging, more moving infrastructure parts — while keeping the monolith's core liability: you still can't change one part without coordinating everyone touching the coupled parts. It is, in a very real sense, worse than either pure architecture, because it maximizes cost while minimizing benefit. ## What it looks like in production In production this shows up as: - coordinated **release trains** ('every other Tuesday, Team A, B, and C deploy together in this order') - **change-freeze windows** spanning multiple 'independent' services - incidents where a bug in one service requires a synchronized multi-service rollback, because rolling back just one breaks the API/schema contract with the others - **testing environments** that require the whole cluster running, because no service can be meaningfully exercised alone Postmortems for such systems repeatedly contain language like 'root cause in Service X caused cascading errors in Service Y,' even though Y's team made no change that day. ## The documented example A well-known, publicly documented real-world example is Segment's 2018-2020 experience: after aggressively decomposing a monolith into many small services, the engineering team found that a large share of their operational pain came from exactly this pattern — services that looked independent on an architecture diagram but were, in practice, tightly coupled through shared infrastructure, cross-service calls, and shared ownership friction, forcing coordinated changes and complicating on-call. Segment published a well-known account of consolidating some of those services back toward a more monolithic structure specifically to eliminate this **coordination tax**. The lesson generalizes: decomposition without addressing the underlying data and call-graph coupling doesn't buy autonomy, it just relocates the coupling onto a network, and the fix is not 'un-splitting' as a rule but genuinely resolving the data ownership and call-chain issues driving the coupling, of which the Segment consolidation was one team's chosen remedy for their specific context.
- If two services are always deployed together, does that alone prove it's a distributed monolith?Not necessarily - it's a strong signal but you need to check why. If it's because of a genuine, rare, coordinated schema or contract change, that's normal evolution; if every routine change to Service A forces a Service B redeploy, that's structural coupling and a real red flag. The distinguishing question is whether the coupling is incidental (once in the app's history) or systemic (every sprint).
- Can a system with only one shared database ever be considered proper microservices?Generally no in the strict sense - database-per-service is one of the core tenets because a shared schema is a shared contract that any service can silently break for another. Some teams tolerate a shared database temporarily during a strangler-fig migration, but that's explicitly a transitional, not end, state.
- How is a distributed monolith different from a poorly-modularized regular monolith?A poorly modularized monolith has the coupling problem but at least keeps deploys, transactions, and debugging local to one process. A distributed monolith adds network calls, serialization, and partial-failure modes on top of the same coupling, so you get the monolith's coordination cost plus the microservice's operational cost simultaneously.
Like six 'independent' food trucks that all draw ingredients from one shared walk-in fridge parked centrally - they look separate on the street, but if the fridge changes its shelf layout, every truck has to stop serving at the same time.
saying these in an interview costs you the question
- Says microservices just means 'services running in different processes' without mentioning independent deployability
- Can't name a symptom beyond 'it's when services talk to each other a lot'
- Doesn't recognize shared-database or synchronous call chains as causes
- Thinks splitting a codebase into repos automatically decouples it