In this article
Use an order as a boundary test
Imagine a product with catalogue, ordering and invoicing capabilities. A modular monolith can keep them in one deployment while exposing explicit interfaces between modules. Ordering should not directly edit invoice tables just because the database is shared. A useful boundary makes business ownership visible before it becomes a network boundary.
Walk through “cancel an order after an invoice was issued”. Which module decides whether cancellation is allowed? Which records must change together? Where does compensation happen? If the team cannot answer these questions inside one process, splitting the code into services will distribute the ambiguity. Tools such as Spring Modulith can help model application modules; the underlying domain decisions still belong to the team.
Where does the boundary live?
Both approaches need clear business ownership.
Modular monolith
Modules in one deployment. Boundaries are enforced inside the application.
Microservices
Independent deployments. Boundaries also cross networks, data stores and operations.
Default to the smallest operable boundary
A modular monolith keeps deployment, observability and data consistency in one operable unit while still enforcing domain boundaries in code. It is often the safer baseline when one team owns the product and workloads share a release rhythm.
Microservices become useful when independent ownership, scaling, availability or release constraints are real and persistent. Splitting earlier only converts code boundaries into network, data and incident boundaries.
Test boundaries before distributing them
Define modules around business capabilities, make dependency direction explicit and prevent cross-module table access. If the modular model cannot survive inside one process, it will not become clearer after adding APIs and queues.
Track which modules change together, contend for resources or need different reliability. Those observations are stronger extraction signals than class count or repository size.
Extract with a recovery plan
Before extracting a service, assign an owner, define its data authority, failure behavior, compatibility window, telemetry and rollback path. Dual writes without reconciliation create two competing truths.
Extract one justified boundary, measure whether it removed the original constraint, and keep the remaining system simple. A distributed architecture is a continuing operating commitment, not a one-time refactor.
What extraction adds to an ordinary request
After invoicing becomes a separate service, an order can be accepted while invoice creation is delayed. The interface must communicate that intermediate state. A retry must not issue a second invoice, and an older event must not overwrite a newer cancellation. These are product behaviours as much as infrastructure concerns.
Before extraction, draw the states and the owner of each transition. Decide where a customer sees “pending”, which process reconciles unresolved work and who investigates a stuck item. If the team needs an all-or-nothing transaction across every change, first question the proposed boundary. Keeping tightly coupled work together may be the more honest design until the business can tolerate and explain partial progress.
Extract one capability and measure the result
A convincing extraction candidate has a specific pressure: a separate release cadence, an independent ownership team or a resource profile that materially differs from the rest. Establish the baseline first. Then move one interface and its data ownership, preserve compatibility during rollout and observe whether the original pressure actually decreases.
Review deployment coordination, on-call workload and the time needed to trace a customer request. If every change still requires all teams to deploy together, you may have created a distributed monolith. Stop further extraction until the coupling is understood. The goal is a system whose boundaries match the work, not a target number of services or a diagram that looks more sophisticated.
Sources & further reading
Documentation consulted on .
FAQ / DECISIONS
Frequently asked questions
Do microservices scale better by default?+
No. They allow independent scaling when boundaries and workloads support it, but add network, consistency, deployment and incident costs.