Bounded Contexts
Explicit boundaries within which a domain model applies and terms have consistent meaning — the cornerstone of modular system design.
What it is
A bounded context, as defined in Eric Evans' Domain-Driven Design, is an explicit boundary within which a particular domain model is defined and applicable. Within a bounded context, every term in the ubiquitous language — the shared vocabulary of developers and domain experts — has one precise meaning. The same word can mean different things in different bounded contexts, and that is intentional: it reflects the reality that different parts of a business think about the same concept differently.
The classic example is the concept of "Customer." In the sales context, a customer is a prospect who has agreed to a contract. In the support context, a customer is anyone who opens a ticket. In the billing context, a customer is an account with a payment method. These are different concepts that share a name, and trying to unify them into a single canonical Customer model is the root cause of countless monolith complexity problems.
Why it exists
Large systems fail because the implicit assumption that "everyone means the same thing when they say X" breaks down under organizational and technical scale. When a single domain model tries to serve all contexts — the "God Object" or "canonical data model" antipattern — it becomes a source of constant conflict, unintended coupling, and brittleness. Every change to the shared model risks breaking all consumers.
Bounded contexts resolve this by making the ambiguity explicit and controlled. Each context owns its own model, its own data, and its own ubiquitous language. Interactions between contexts are managed through well-defined integration patterns (context mappings) rather than shared object graphs. This enables independent development, deployment, and evolution of each context — which is the basis for microservices architecture done well.
When to use
- When a system serves multiple distinct business capabilities or departments that use the same terms with different meanings.
- When designing a microservices architecture — bounded contexts provide the intellectual framework for drawing service boundaries correctly.
- When decomposing a monolith — identifying bounded contexts reveals the natural seams along which the system can be split.
- When multiple teams own different parts of the same codebase and need clear ownership boundaries.
- When building an event-driven system and needing to decide which events belong to which context.
When not to use
- Do not apply bounded contexts to simple CRUD applications with a single business domain — the overhead is unjustified.
- Do not create a bounded context for every database table or entity; contexts represent cohesive business capabilities, not data structures.
- Do not force a 1:1 mapping between bounded contexts and microservices; one context can be implemented as multiple services, or multiple small contexts can share one service.
Typical architecture
A context map is the DDD artifact that shows all bounded contexts in a system and the relationships between them. The six primary context mapping patterns describe different power and integration dynamics. The diagram below shows a simplified e-commerce context map.
E-Commerce Context Map:
────────────────────────────────────────────────────────────
┌───────────────────┐ Shared Kernel ┌──────────────────┐
│ Catalog │◄───(shared Product ID)──►│ Inventory │
│ Context │ │ Context │
└────────┬──────────┘ └──────────────────┘
│ Customer/Supplier
│ (Catalog = Supplier)
▼
┌───────────────────┐
│ Order │──── ACL (Anti-Corruption Layer) ────►┌────────────┐
│ Context │ │ Payment │
└────────┬──────────┘ │ Context │
│ Published Language (OrderPlaced event) └────────────┘
▼
┌───────────────────┐
│ Fulfillment │
│ Context │
└───────────────────┘
Context Mapping Patterns:
Shared Kernel — both contexts share a small, carefully guarded model subset
Customer/Supplier — upstream supplies, downstream consumes; downstream has input into upstream
Conformist — downstream conforms to upstream's model with no influence
ACL — Anti-Corruption Layer translates between incompatible models
Open Host Service — upstream publishes a formal protocol for downstream consumers
Published Language — a shared, documented exchange language (e.g., canonical events)
Pros and cons
Pros
- Eliminates the "canonical model" antipattern — each context can model its domain without compromising for others.
- Enables independent deployment and evolution of different parts of the system.
- Provides a principled basis for team ownership — Conway's Law is respected rather than fought.
- Makes cross-context integration explicit and deliberately managed rather than implicit and accidental.
- Scales naturally to large organizations with many teams and many sub-domains.
Cons
- Requires significant upfront domain analysis to draw context boundaries correctly — premature boundaries are expensive to fix.
- Cross-context queries (e.g., a report that joins data from three contexts) become complex and require aggregation patterns.
- Data duplication is intentional and necessary — the same logical entity exists in multiple contexts with different representations.
- Requires organizational alignment: context boundaries work best when they align with team boundaries (Conway's Law).
Implementation notes
Identifying context boundaries: The most reliable technique is Event Storming — a facilitated workshop where domain events are placed on a timeline, and the natural groupings of events around a specific vocabulary and responsibility reveal context boundaries. Other indicators: different teams own different nouns with the same name, data that needs to change at different rates, different deployment lifecycles, and areas where different business units have ownership disputes.
Anti-Corruption Layer (ACL): When a bounded context must integrate with a legacy system, a third-party service, or a context with a model that conflicts with its own, the ACL acts as a translation layer. It converts the upstream model into the downstream context's model at the integration boundary, protecting the downstream from upstream model changes. This is arguably the most important context mapping pattern for real-world systems.
Bounded contexts and microservices: Bounded contexts are a logical concept; microservices are a deployment and operational concept. A bounded context should never be split across multiple services in ways that require distributed transactions (this is the "service mesh of death" antipattern). Multiple small bounded contexts can co-exist in a modular monolith before being extracted into separate services when operational independence becomes justified.
Common failure modes
- Shared database across context boundaries: Two services in different bounded contexts sharing a database table directly — this eliminates all the independence benefits of bounded contexts.
- Anemic context boundary: A context that contains a single entity or is defined by a data type rather than a business capability.
- Missing ACL: Consuming a legacy system's model directly, polluting the downstream context with the upstream's poor design choices.
- Premature decomposition: Defining twenty bounded contexts before understanding the domain well, resulting in the wrong boundaries that are expensive to fix.
- Ignoring the ubiquitous language: Having a "bounded context" in name only, with no shared vocabulary between developers and domain experts.
Decision checklist
- Have we conducted domain discovery (event storming or domain interviews) to identify natural context boundaries before drawing service lines?
- Does each bounded context have a clearly named ubiquitous language documented and shared with domain experts?
- Does each context own its own data store exclusively — no shared databases across context boundaries?
- Have cross-context relationships been mapped and assigned a context mapping pattern (ACL, customer/supplier, etc.)?
- Do context boundaries align with team ownership boundaries to leverage Conway's Law?
- For any legacy system integration, is there an explicit Anti-Corruption Layer rather than direct model sharing?
- Have we validated that no bounded context requires distributed transactions across another context to satisfy business invariants?
Example use cases
- An e-commerce platform identifies Catalog, Inventory, Ordering, Fulfillment, Billing, and Customer Support as six distinct bounded contexts, each owned by a separate team with its own data store.
- A healthcare system uses an ACL to integrate with an HL7 FHIR legacy EHR, translating FHIR Patient resources into the local context's Patient aggregate without exposing FHIR concepts to the domain model.
- A logistics company identifies that "Shipment" means something different in the quoting context (a priced request), the operations context (a physical movement), and the billing context (an invoice line), and models three separate aggregates with an event-based integration.
Related patterns
- Domain Modeling — the tactical DDD patterns used within a bounded context.
- Architecture Principles — bounded contexts apply the SRP and high cohesion principles at the domain level.
- Architecture Styles — microservices architecture uses bounded contexts as the primary service decomposition tool.
Further reading
- Domain-Driven Design — Eric Evans — the original DDD book that introduced bounded contexts.
- Implementing Domain-Driven Design — Vaughn Vernon — comprehensive guide to applying DDD in practice, with detailed context mapping coverage.
- BoundedContext — Martin Fowler — concise explanation of bounded contexts and their relationship to microservices.