Course outline

Software Architecture / Interactions: distribution, failure, and operation / Lesson 7

Choose deployment boundaries from real independence needs

Compare a modular monolith and autonomous services without treating distribution as a maturity badge.

About 4 min readContent reviewed
On this page

Lesson goals

  • Separate logical modularity from process and deployment separation.
  • Evaluate a proposed service split using ownership, data, and failure consequences.

A module and a deployable service answer different questions

A modular monolith packages several well-defined responsibilities into one deployable application. Services place selected responsibilities behind process and network boundaries, ideally with independent ownership and release capability. Either design can have good or poor internal structure. Distribution changes the cost of communication and failure: a local call becomes a remote interaction with latency, partial availability, and uncertain outcomes. Choose that cost when it buys a needed capability, rather than assuming that more processes automatically improve maintainability, performance, or team productivity.

Look for a coherent business capability

The workshop example contains catalog browsing, seat reservation, and notification delivery. A notification worker may deserve separate scaling because slow providers should not occupy reservation request threads. Splitting data access into a universal database service, however, can force every business action through a shared bottleneck and expose storage details. A useful service boundary contains its business knowledge and owns its writes. Bounded contexts help identify where terms change meaning; they are modeling boundaries and do not mechanically require a separate service for every context.

yaml A service-boundary hypothesis
candidate: notification delivery
independent_need: provider latency varies from reservation latency
owned_state: delivery attempts and delivery outcome
input: ReservationConfirmed event
excluded: seat allocation and capacity decisions

The hypothesis names the reason for separation and the state it owns. It still needs delivery, security, and migration design before it can become an implementation plan.

Test whether releases are actually independent

If every notification release requires a simultaneous booking release, shared schema update, and coordinated database migration, the process boundary may have created a distributed monolith. Some coordination is normal, but frequent lockstep changes suggest unstable contracts or a misplaced responsibility. Review a realistic change such as adding a delivery channel: which repositories, contracts, teams, and deployment steps must change? Independent deployment is a capability to demonstrate with compatible interfaces and data ownership, not a property established by separate repository names or container images.

Compare complete operating costs

The comparison below is intentionally qualitative. A single deployable application has a shared release and process failure boundary; that may be appropriate for one team and an atomic reservation transaction. Separate services can isolate scaling and ownership but need service identity, telemetry, network policy, contract evolution, and recovery procedures. Avoid scoring every feature with arbitrary weights that hide assumptions. Use the highest-priority quality scenarios and current capabilities to explain why one cost is acceptable and another is currently unnecessary.

text Two options for the same workload
Option A: one application, explicit internal booking/notification modules
Benefit: local calls and one reservation transaction boundary
Cost: shared release and process resources
Option B: booking application plus notification worker
Benefit: independent worker concurrency and provider isolation
Cost: durable messages, deduplication, and cross-process telemetry

Neither option is declared universally superior. The worker option becomes useful only if the isolated delivery workload and its additional operational requirements are justified.

Preserve a path to change the boundary

Begin with explicit module interfaces and authoritative data ownership even when everything ships together. These practices make later extraction more tractable, although a network boundary still requires new failure semantics and deployment work. Extract one coherent workflow through a staged migration with observability and rollback criteria. Recombine services if evidence shows that the split adds coordination without useful autonomy. Architecture is allowed to evolve in both directions; maintaining an unsuitable split merely to protect an earlier diagram increases cost without serving users.

Common errors and fixes

Every database table becomes a service.

Why it happens
Storage structure replaced business capability modeling.
How to fix it
Group operations around cohesive knowledge and invariants.
Prevent it next time
Walk through representative business changes before splitting.

All services must release together.

Why it happens
Shared internals and breaking contracts preserved lockstep coupling.
How to fix it
Stabilize contracts or reconsider the split.
Prevent it next time
Track coordinated-release causes rather than counting deployments.

Distribution is expected to remove team coordination.

Why it happens
Organizational ownership and shared policies were not addressed.
How to fix it
Assign contract, data, and operational owners explicitly.
Prevent it next time
Include operating capability in architecture evaluation.

Check your understanding

1. A small team has reliable releases but a slow email provider. Must it create microservices for every capability?

Show worked solution

No. An internal delivery abstraction and a durable background worker may isolate the specific bottleneck without splitting catalog and reservation ownership. Compare a worker process with other options against latency and recovery scenarios. Preserve the reservation invariant and define delayed-notification behavior. The evidence justifies a targeted boundary, not an entire distributed platform.

2. What evidence would support extracting the catalog later?

Show worked solution

Demonstrate distinct ownership or scaling needs, a stable query contract, a clear source of catalog writes, and tolerance for any replicated-view delay. Show how an independent catalog release avoids a booking release and how failures affect reservation behavior. Without those facts, extraction may move coupling onto a network instead of reducing it.

Key takeaways

  • Choose distribution for a demonstrated capability and its costs.
  • Logical ownership matters before and after service extraction.

Official references