MicroservicePatterns.com

Suggestions

  • PagePattern catalogAll patterns by category.
  • LabCircuit Breaker and Retries labCrash a dependency and tune the breaker.
  • LabSaga labFail a step and watch the compensations run.
  • PagePractice questionsScenario questions with explanations.
  • PageDesign reviewCheck your own architecture for anti-patterns.
Decomposition · Comparison

Decompose by Subdomain vs by Business Capability

Both patterns answer the same question: where should the service boundaries go? Business capabilities describe what the business does. Subdomains describe how the problem is modelled and where words change meaning. Neither is better in general: they work at different levels. Capabilities give stable boundaries the whole business understands, and subdomains find the precise model boundaries inside them. Most systems need both, one after the other.

Updated

At a glance

What is the difference?

Business capability and subdomain decomposition compared
AspectBy business capabilityBy subdomain
The question it asksWhat does the business do?Where does the meaning of the model change?
Where boundaries come fromA capability map, built with people who run the businessThe domain model: bounded contexts found with domain experts, for example in event storming
Main outputA hierarchy of capabilities, each with an owning teamBounded contexts, each subdomain marked core, supporting or generic, and a context map
Shared words such as Order or CustomerNot addressed directly. One capability usually ends up owning the shared modelHandled directly. Each context keeps its own model of the word
Where to investCapability heat maps rate each capability's strategic value and maturity, to guide investment across the businessFiner-grained: core subdomains get the most effort, generic ones are bought
Who can read the resultAnyone in the business, from executives to financeMostly engineers and domain experts who know the domain-driven design vocabulary
How stable the boundaries areVery stable. What a business does changes slowly and survives reorganisationsCan shift as the team learns more about the domain and refines its models
Effort to applyLower. A first map can come out of one workshopHigher. Needs domain experts and some practice with domain-driven design
Strengths

Where is each approach strongest?

The worked example below shows where subdomain analysis refines a capability map. That does not make it the better method everywhere: each one has situations where it is the stronger choice.

Business capability is the better fit when:

  • You need team and ownership boundaries that executives, product and finance can agree on and fund.
  • Boundaries have to last through reorganisations, product changes and new leadership.
  • The team has little domain-driven design experience or little access to domain experts.
  • The domain is fairly simple and data-centred, so words like Customer or Order mean much the same to everyone.
  • Much of the landscape is bought software, such as an ERP, CRM or SaaS products, and the question is which system owns what.
  • You are planning across a whole portfolio of systems, for example after a merger or when deciding where to invest.

Subdomain is the better fit when:

  • The domain is complex, as in logistics, insurance, healthcare or finance.
  • The same word means different things to different groups, so one shared model keeps growing.
  • You need to decide what to build in-house and what to buy.
  • You are drawing precise boundaries for one service or a small group, where an unclear model costs the most.
Worked example · fictional company

Step 1: decompose Brindle Eats by business capability

Brindle Eats is a food-delivery platform: consumers order from restaurants, kitchens cook and couriers deliver. Ask the people who run it what the business does, and a first capability map comes out of one workshop.

  • Restaurant Management

    Onboard restaurants, manage menus and opening hours

  • Consumer Management

    Sign-up, profiles, saved addresses

  • Order Management

    Take orders and track them to completion

  • Delivery Management

    Assign couriers and track deliveries

  • Accounting

    Charge consumers, pay restaurants and couriers

Result: five services, one per capability, each with an owning team. Everyone in the company recognises the boxes. So far, so good.

Where it starts to hurt

Why does one word cause trouble?

Order Management owns “the order”, but nearly everyone needs it, and each group means something different by it.

What Order means to four groups at Brindle Eats
WhoWhat “Order” meansFields they care about
ConsumerWhat I bought and what it costline items, prices, promo code, total ($), payment status
KitchenWhat we need to cook, and by whendishes, modifiers ("no onions"), prep time, ready-by time
CourierWhat I pick up and where it goespickup address, drop-off address, ready time, bag count
FinanceWhich money moves wheregross amount, fees, tax, restaurant payout, courier payout

With one Order Service and one Order model:

  • The Order model grows to dozens of fields, each added by a different team.
  • A kitchen change, such as a new prep station field, means retesting the courier's code.
  • Every service calls Order Service for its slice of the data, so it becomes a bottleneck and a single point of failure.
  • Nobody can say who approves a change to the Order schema.

Capability decomposition did not cause this, but nothing in it warns you about it either.

Step 2

How does decomposing by subdomain change the boundaries?

Run an event-storming session with a restaurant manager, a dispatcher and someone from finance, and lay out what happens in order:

  1. Order placed
  2. Payment authorized
  3. Ticket accepted
  4. Food prepared
  5. Courier assigned
  6. Food picked up
  7. Food delivered
  8. Restaurant paid

Then listen for where the language changes. Kitchen staff do not say order, they say ticket. Dispatchers talk about deliveries and couriers. Each change of vocabulary marks the edge of a bounded context with its own model. When an order is placed, the kitchen creates a ticket and dispatch creates a delivery, each keeping only the data it needs.

  1. Restaurant ManagementOne service
    Same
    • Restaurant ServiceRestaurant, Menusupporting

    Same boundary either way.

  2. Consumer ManagementOne service
    Same
    • Consumer ServiceConsumer, Addresssupporting

    Same boundary either way.

  3. Order ManagementOne service
    Split
    • Order ServiceOrder (the consumer's view)supporting
    • Kitchen ServiceTicketsupporting

    Kitchen staff talk about tickets, not orders. A ticket has its own lifecycle, so it gets its own context.

  4. Delivery ManagementOne service
    Split
    • Dispatch ServiceCourier match, ETAcore
    • Delivery TrackingDelivery, courier locationsupporting

    Matching couriers to orders is what makes Brindle Eats faster than its rivals. That core subdomain gets its own service and the strongest team.

  5. AccountingOne service
    Reshaped
    • BillingCharge (via a payment provider)generic
    • PayoutsPayout, ledger entrysupporting

    Charging cards is generic, so Billing is a thin wrapper around a bought payment provider, not something built in-house.

Five capability services become eight subdomain services. Two boundaries stay the same, two capabilities split along a change in language, and one is reshaped once you see that card payments are generic.
Step 3

Which subdomains deserve the most effort?

A capability heat map can show which capabilities matter most. Subdomain classification goes a level finer, inside a capability. That is why Delivery Management split into a core Dispatch Service, and why Billing is bought, not built.

  • Core

    What sets you apart from competitors. Build it in-house, give it your best engineers and change it often.

    At Brindle Eats: Courier dispatch and matching, delivery time estimates

  • Supporting

    Needed to run the business but not a differentiator. Build it, and keep it simple.

    At Brindle Eats: Restaurant onboarding, menus, kitchen tickets, payouts

  • Generic

    Every business has it. Buy or use an off-the-shelf product unless there is a strong reason not to.

    At Brindle Eats: Card payments, sign-in, email and SMS, tax calculation

A second example

One “Product” in e-commerce, five models

A capability map often has one Product Management box, which tempts teams to build one Product service with every field. Subdomain analysis finds five small models that share only a product ID.

What Product means in five bounded contexts
ContextWhat “Product” meansIts fields
CatalogSomething to show and searchtitle, description, images, category
PricingSomething with a price that changesbase price ($19.99), discounts, price rules
InventoryA physical item in a warehouseSKU, warehouse, quantity on hand, reserved
ShippingA parcel to moveweight, dimensions, hazardous goods flag
ReviewsSomething people raterating, review text
Real-world examples

How have real systems drawn these boundaries?

  • Grouping services into domains

    Uber

    In 2020 Uber described Domain-Oriented Microservice Architecture (DOMA). It grouped around 2,200 critical microservices into about 70 domains. Each domain has a gateway as its single entry point, and domains sit in five layers: infrastructure, business, product, presentation and edge. Uber says the approach draws heavily on domain-driven design.

    Lesson: Many small services with no domain structure become hard to understand and change. Subdomain thinking can bring that structure back after the fact.

    Source: Introducing Domain-Oriented Microservice Architecture (Uber, 2020)

  • Business domains inside a monolith

    Shopify

    In 2019 Shopify described reorganising its Rails monolith around real-world business domains, such as orders, shipping, inventory and billing, instead of models, views and controllers. It enforced the boundaries between these components and chose a modular monolith over microservices.

    Lesson: You can find and enforce business boundaries inside one codebase first, and extract services later only where you need them.

    Source: Deconstructing the Monolith (Shopify Engineering, 2019)

  • Reference application

    FTGO

    The example application for Chris Richardson's book Microservices Patterns is a food-delivery system much like the one above. Next to its Order Service it has a separate Kitchen Service, along with Consumer, Restaurant, Accounting and Delivery services.

    Lesson: A worked codebase you can read to see how a kitchen context sits next to ordering in practice.

    Source: ftgo-application (GitHub)

Pitfalls

What mistakes do both approaches prevent?

  • One service per table

    CustomerService, ProductService and OrderService as thin wrappers over tables. Every business operation becomes a chain of calls, and the logic has no home.

  • One service per technical layer

    A UI service, a business logic service and a data service. Every feature has to change all three.

  • Copying the org chart

    Boundaries that follow today's departments break at the next reorganisation. Capabilities change more slowly than departments.

  • Too fine-grained too early

    One service per entity or use case before you know the domain. Start coarse and split when you see real pressure.

  • Boundaries without data ownership

    A clean service map that still shares one database. The coupling just moves into the schema.

Choosing

When should you use each?

Which approach to lean toward in each situation
SituationLean toward
A large organisation that needs team boundaries soonBusiness capability
You already have a capability map or an enterprise architecture functionBusiness capability
Much of the landscape is bought software, such as an ERP, CRM or SaaSBusiness capability
Little access to domain experts or experience with domain-driven designBusiness capability
A complex domain, such as logistics, insurance, healthcare or financeSubdomain
The same word means different things to different teamsSubdomain
You need to decide what to build and what to buySubdomain
A small team and a simple domainEither, or a modular monolith first

A practical recipe that uses both:

  1. Sketch the capability map. Get rough boxes that make sense to the business, and match them to teams.
  2. Event-storm across the boxes. Find where the language changes, and move boundaries to follow it.
  3. Classify each subdomain. Core, supporting or generic. Put effort where it differentiates, and buy the rest.
  4. Draw the context map. Decide how contexts talk: events, APIs and translation at the edges.
  5. Extract only where it pays. Start as a modular monolith if unsure, and split out services where scaling, release speed or team autonomy need it.

Read the full pattern pages for Decompose by Business Capability and Decompose by Subdomain, or see how teams line up with these boundaries in teams and ownership.

Keep going

What next?