advanced 2 min answer

A platform decomposes a monolith into services. Which boundaries should be extracted first, and which extraction produces a distributed monolith?

decompositionboundariescouplingdistributed-monolithtwiliodesign
Show the full answer Hide the answer

Which to extract first

The boundary with a different scaling profile, failure tolerance or change cadence, and stable interfaces. Concretely, good first candidates share these properties:

  • It changes independently of the rest, demonstrated over time rather than assumed.
  • Its data is genuinely its own, so extraction does not require splitting a transaction.
  • It has a different operational profile — much higher volume, much longer-running work, much stricter latency, or a different availability requirement.
  • It has a clear owner, so the boundary is maintained by the organisation as well as the code.

For a communications platform, the classic first extraction is the message delivery path: high volume, long-running, different failure semantics from the API tier, and it needs to scale on a completely different curve.

Which extraction produces a distributed monolith

A boundary whose components still change together and still require coordinated deployment. The signature symptoms:

  • A release requires several services to ship together, so nothing was decoupled.
  • A single business change touches four services, meaning one piece of knowledge has four implementations — content coupling dressed up as service boundaries.
  • Services share a database, so the schema is a shared, unversioned interface.
  • A synchronous call chain across all of them, so availability is now the product of several services and latency is their sum.

The result has the operational cost of distribution and the change cost of a monolith — worse than either.

The test before extracting

Has this module changed independently of its neighbours for a meaningful period? If not, extracting it guesses at a boundary, and a wrong service boundary is far more expensive to correct than a wrong module boundary.

Establish the boundary as a module first, with enforced dependency rules, and let the change history produce the evidence. Teams that skip this step choose boundaries from a diagram and discover them from incidents.

The other decomposition question

Extract only the bottleneck. If the driver is that one subsystem needs materially more resource than the rest, extracting that subsystem addresses it. Decomposing the entire application because one part has a scaling problem buys a large amount of distributed-systems cost for a benefit that one extraction would have delivered.