Bounded Contexts and Context Mapping
Ask Sales, Billing, and Support what a "customer" is and you get three different answers. To Sales, a customer is a lead with a pipeline stage and an account owner. To Billing, it is a legal entity with a tax region, payment method, and credit limit. To Support, it is a set of people with entitlements and open tickets. Forcing all three into one Customer class produces a model that serves nobody well and that every team fears changing.
A bounded context is the explicit boundary within which one model and its language are consistent. Inside it, "customer" means exactly one thing. Context mapping describes how those contexts relate — who depends on whom, how models are translated at the edges, and how teams coordinate. Together they are the most useful ideas in strategic domain-driven design, and they shape modules, services, and team boundaries.
TL;DR
- A bounded context is a boundary around one consistent model and ubiquitous language.
- The same word can legitimately mean different things in different contexts; that is a signal of a boundary, not a problem to eliminate.
- Subdomains (core, supporting, generic) describe the business; bounded contexts describe your solution.
- A context map records relationships: partnership, shared kernel, customer-supplier, conformist, anticorruption layer, open host service, published language, separate ways.
- Protect your core model from external or legacy models with an anticorruption layer.
- Contexts often align with teams and can be modules in a monolith before (or instead of) becoming services.
Quick Example
A small context map for an online store, written as text that lives beside the code:
Billing's anticorruption layer translates the legacy CRM's record into Billing's own model, so CRM naming and quirks never leak into the domain:
Core Concepts
Bounded Contexts
Within a bounded context, every term has one meaning, the model is internally consistent, and one team owns it. Across contexts, the same real-world thing can be modeled differently, because each context needs different data and rules. Integration happens at the boundaries through explicit contracts — APIs, events, or shared data with clear ownership.
Subdomains Versus Contexts
Invest deep modeling in core subdomains, build supporting ones simply, and buy or reuse generic ones such as identity, email, or payments.
Signals of a Boundary
- The same word means different things, or different words mean the same thing.
- Different rules apply to the same data depending on who uses it.
- Different teams, change rates, or stakeholders own different parts.
- A model has grown so many optional fields that most code ignores most of them.
Discovering Contexts
EventStorming workshops map a business process as a timeline of domain events with domain experts, then look for pivotal events and language shifts where boundaries naturally fall. Domain storytelling and simple interviews about "what does X mean to you?" reveal the same seams.
Context Map Patterns
Upstream contexts influence downstream ones; the map shows which way that influence flows, which tells you where translation and negotiation are needed.
Contexts, Teams, and Services
- Teams: a bounded context should be owned by one team; Conway's law means team boundaries and context boundaries shape each other. See Team Topologies.
- Modules first: contexts work well as modules in a modular monolith, with enforced dependencies and separate schemas, before any network boundary. See Monolith vs Microservices.
- Services: a microservice should not span contexts; a context may contain several services if it is large.
- Data: each context owns its data; others get it through APIs or domain events, not by reading its tables.
Best Practices
Draw the Map, Then Keep It Current
A context map that lives in the repository and is updated during design reviews is far more useful than a workshop photo. Include relationship patterns and owning teams.
Keep Shared Kernels Tiny
Shared models create coupling between teams. Share only what genuinely must be identical, version it, and change it jointly.
Translate at the Edges
Use anticorruption layers and mappers so external or legacy models never appear inside your domain code. The translation layer is where integration complexity belongs.
Publish Contracts Deliberately
Expose stable, documented events and APIs as a published language rather than internal entities, so internal models can change freely.
Common Mistakes
One Enterprise-Wide Model
Contexts Drawn Around Technical Layers
Services Sharing a Database
FAQ
What is a bounded context?
An explicit boundary within which a domain model and its language are consistent and owned by one team. Outside the boundary, the same terms may mean different things and are modeled separately.
Is a bounded context the same as a microservice?
No. A bounded context is a model and language boundary. It may be implemented as a module in a monolith, one service, or several services, but a single service should not span multiple contexts.
What is an anticorruption layer?
A translation layer that converts another context's or system's model into your own, protecting your domain model from external naming, structure, and assumptions — commonly used with legacy and third-party systems.
How do I find bounded contexts?
Look for language differences, different rules for the same data, team and stakeholder boundaries, and pivotal business events. Workshops such as EventStorming with domain experts are an effective way to surface them.
What is a context map?
A diagram or document that shows bounded contexts and the relationships between them — which are upstream or downstream and which integration patterns connect them — so teams understand dependencies and translation points.
Related Topics
- Domain-Driven Design — Strategic and tactical DDD
- Domain Events — Integrating contexts through events
- Microservices — Services aligned with contexts
- Monolith vs Microservices — Modules before services
- Team Topologies — Aligning teams with boundaries
- Hexagonal Architecture — Ports and adapters at context edges