Domain-Driven Design: Bounded Contexts Explained

Understand DDD bounded contexts — how to decompose a complex domain into autonomous modules with clear boundaries, shared kernels, and anti-corruption layers.


Domain-Driven Design: Bounded Contexts Explained

Bounded Contexts are the central pattern in Domain-Driven Design (DDD). They define explicit boundaries within which a domain model is consistent and meaningful.


The Problem: One Model Doesn't Fit All

In a large system, the same word means different things in different parts of the business:

TermIn SalesIn WarehouseIn Accounting
OrderA customer's purchase intent with pricing and discountsA pick list with bin locations and weightsAn invoice with tax calculations and payment terms
ProductSKU with marketing copy, images, and reviewsPhysical item with dimensions, weight, and storage classRevenue line item with cost-of-goods and margin
CustomerLead/prospect with conversion funnel dataShipping address and delivery preferencesBilling entity with credit terms and payment history

Forcing one unified model creates a Big Ball of Mud — a model that's too complex, too coupled, and too fragile.


The Solution: Bounded Contexts

Each bounded context:

  • Has its own ubiquitous language (terms, rules, invariants).
  • Owns its own data store (or at minimum, its own schema/tables).
  • Communicates with other contexts via well-defined interfaces (events, APIs, shared kernel).
Rendering diagram…

Context Mapping Patterns

How bounded contexts relate to each other:

Rendering diagram…

Pattern Summary

PatternDescription
Shared KernelTwo contexts share a small common model (e.g., Money, Address). Both teams co-own it.
Anti-Corruption Layer (ACL)Downstream context translates upstream models into its own language. Protects from upstream changes.
Open Host ServiceUpstream exposes a well-defined API/protocol for multiple consumers.
Published LanguageA shared schema (e.g., JSON Schema, Protobuf) that both sides agree on.
Customer–SupplierUpstream prioritises downstream's needs.
ConformistDownstream adopts upstream's model as-is (no translation). Simplest but most coupled.

Identifying Bounded Contexts

  1. Listen for language shifts — When the same word has different meanings, you've crossed a boundary.
  2. Look for independent lifecycles — If two parts of the system change for different business reasons, they're likely separate contexts.
  3. Follow the data ownership — Who is the authoritative source for this data?
  4. Watch for team boundaries — Conway's Law: system structure follows team structure.

Bounded Contexts in Practice

Modular Monolith

Bounded contexts don't require microservices. A modular monolith enforces context boundaries via:

  • Separate modules/packages with explicit public APIs.
  • Shared database with per-context schemas.
  • In-process event bus for async communication.

Microservices

Each microservice is a bounded context (ideally). Inter-service communication happens via:

  • Domain events (async, preferred).
  • REST/gRPC APIs (sync, for queries).
  • Anti-corruption layers at service boundaries.

Further Reading