Bounded Context
Bounded Context
"A description of a boundary (typically a subsystem, or the work of a particular team) within which a particular model is defined and applicable." — Eric Evans, Domain-Driven Design (2003)
Intent
A Bounded Context is an explicit boundary within which a single, consistent domain model is valid. Inside the boundary, every term in the ubiquitous language has a precise, unambiguous meaning agreed upon by developers and domain experts. The same word can mean different things in different contexts — "Customer" in a Sales context (a prospect being converted) is not the same concept as "Customer" in a Support context (an account holder with a ticket history). These differences are not accidents; they reflect genuine differences in what each sub-domain cares about.
The Bounded Context makes these linguistic boundaries explicit and architectural. Each context owns its own model — its own entities, value objects, and services. When two contexts need to interact, translation is required at the boundary. The nature of that translation relationship is described by the Context Map.
Conway's Law alignment: team boundaries often (and should) align with Bounded Context boundaries. A team that owns one context can evolve its model independently. When team boundaries and context boundaries diverge, model pollution follows — shared codebases lead to semantic drift as different teams add meaning to the same terms.
When NOT to Use
- When the entire system is small enough that one unified model causes no ambiguity — introducing Bounded Contexts into a small, single-team codebase adds coordination overhead without benefit.
- When "bounded contexts" become an excuse to create microservices without genuine domain boundaries. A context boundary must reflect a real semantic difference in the domain, not an engineering preference for independent deployments.
- When the team splitting does not reflect genuine domain separations — Conway's Law alignment must be intentional; forcing context boundaries along team lines when the underlying domain is unified produces artificial translation overhead.
- When the context map would consist of a single context with no relationships — the concept is only meaningful when multiple contexts coexist and interact.
When to Use
- When the same term has genuinely different meanings in different subdomains (the "Customer" / "Account" / "User" naming collision is the canonical signal).
- When different teams own different parts of the domain model and need to evolve them independently without coordinating on every model change.
- When a legacy system must be integrated without corrupting the new domain model — use an Anti-Corruption Layer at the boundary (see Anti-Corruption-Layer-Pattern).
- When scaling teams requires clear ownership boundaries. Bounded Contexts provide the explicit contract: this team owns this model, that team owns theirs.
- When a subdomain's language is genuinely foreign to another subdomain — translation is not a workaround; it is the correct design.
How It Works
A Bounded Context defines an explicit scope within which a domain model — its entities, value objects, domain services, and repositories — is consistent and unambiguous. The ubiquitous language inside a context is the shared vocabulary between developers and domain experts for that context only.
Boundaries can be enforced by several mechanisms (in increasing deployment independence):
- Package/module separation — the simplest form; a dedicated package or namespace per context, within a monolith
- Separate deployable modules — separate JARs or Node packages; shared process but separated compilation units
- Separate services — each context is its own deployable process (microservice); context boundaries become network boundaries
- Separate code repositories — maximum isolation; each context has independent CI/CD, schema, and release cadence
The choice of enforcement mechanism is a deployment and team-topology decision, not a domain modelling decision. A Bounded Context is valid at all four levels. Microservices and Bounded Contexts are not synonymous — every microservice should map to a Bounded Context, but a Bounded Context does not require a microservice.
Context Map Diagram
flowchart LR
subgraph Sales Context
SO[Sales Order]
SC[Customer]
end
subgraph Shipping Context
SH[Shipment]
SA[ShippingAddress]
end
Sales Context -->|"Customer/Supplier<br/>(upstream)"| Shipping Context
subgraph ACL["Anti-Corruption Layer"]
T[Translator]
end
Sales Context --> ACL
ACL -->|"translated<br/>domain model"| Shipping Context
style ACL fill:#f9f,stroke:#333,stroke-dasharray: 5 5
Context Map Overview
A Context Map documents the relationships between Bounded Contexts. Six canonical relationship patterns describe how contexts interact:
| Relationship | Direction | Description |
|---|---|---|
| Shared Kernel | Bidirectional | Two contexts share a small, explicitly agreed subset of the domain model. Changes to the shared kernel require coordination between both teams. High integration confidence, high coordination cost. |
| Customer/Supplier | Upstream/Downstream | Downstream context depends on upstream; upstream plans releases with downstream needs in mind. The downstream team has negotiating power. |
| Conformist | Downstream only | Downstream adopts the upstream's model wholesale — no translation layer. Used when the upstream has no incentive to accommodate downstream needs and the downstream team cannot justify the translation cost. |
| Anti-Corruption Layer | Downstream shield | Downstream context isolates itself from an upstream model via a translation layer, preventing foreign concepts from corrupting the downstream's ubiquitous language. See Anti-Corruption-Layer-Pattern. |
| Open Host Service | Upstream publishes | Upstream context defines a published protocol (API contract, event schema) that multiple downstream contexts integrate against. The protocol is versioned and stable. |
| Separate Ways | None | Two contexts have no integration. Duplication of concepts is accepted because the cost of integration outweighs the benefit. Teams go their own way. |
Note: Full Context Map with team topology, strategic pattern selection guidance, and visual mapping is deferred to Context-Map (v1.x).
Lineage Forward
- Anti-Corruption-Layer-Pattern — The ACL is the implementation pattern for the Anti-Corruption Layer context map relationship. When a Bounded Context integrates with a legacy system or a Conformist upstream, the ACL prevents foreign model concepts from leaking into the domain's ubiquitous language.
- Context-Map (v1.x — deferred) — A full Context Map documents all Bounded Context relationships in the system and informs architectural and team topology decisions.
Related Concepts
| Pattern | Relationship |
|---|---|
| Anti-Corruption-Layer-Pattern | The ACL is the concrete implementation of the Anti-Corruption Layer context map relationship — the boundary enforcement mechanism. |
| Domain-Events | Domain Events raised inside a context are promoted to Integration Events when they cross Bounded Context boundaries. The event contract is translation output. |
| Value-Object | Value Objects are tactical building blocks that operate within a Bounded Context. The same value type (e.g., Money) may have different representations in different contexts. |
| Aggregate | Aggregates are the consistency unit inside a Bounded Context. Aggregate roots are referenced by identity across context boundaries, never by object reference. |
| Repository | Repositories load and save Aggregates inside a Bounded Context. They are never shared across context boundaries. |
Related Architecture Patterns
- Clean-Architecture — The Entities and Use Cases layers define the model valid within a single Bounded Context; context boundaries determine where one Clean Architecture application ends and another begins.
- Modular-Monolith — One module = one Bounded Context expressed in code; module boundaries enforce the same linguistic boundary that a Bounded Context defines in the domain model.
Related System Design
- Database-Sharding — bounded context boundaries are natural vertical shard boundaries; each context owns its data and the CAP-Theorem consistency model applies within each context
- Unique-ID-Generator-Design — each datacenter/service domain owns its worker ID range; the coordination boundary mirrors bounded context isolation — no cross-context worker ID sharing
Sources
- Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley 2003, ch. 14
- Fowler, bliki/BoundedContext — https://martinfowler.com/bliki/BoundedContext.html
- Vernon, Implementing Domain-Driven Design, Addison-Wesley 2013, ch. 2