Domain-Driven Design: Getting Bounded Contexts Right
Practical bounded context design with context mapping patterns, event storming for boundary identification, and real domain examples from e-commerce and fintech.
Akhil Sharma
February 23, 2026
Domain-Driven Design: Getting Bounded Contexts Right
Bounded contexts are the most important and least understood concept in Domain-Driven Design. Teams either draw them too small (one context per entity, leading to distributed monolith hell) or too large (one context for everything, leading to a traditional monolith with DDD vocabulary).
The right boundaries come from understanding where language changes — where the same word means different things to different parts of the business.
What a Bounded Context Actually Is
A bounded context is a boundary within which a particular domain model is consistent. The word "Product" means different things in different parts of the business:
- Catalog context: Product has a name, description, images, categories, SEO metadata
- Inventory context: Product has a SKU, warehouse location, quantity on hand, reorder threshold
- Pricing context: Product has a base price, discount rules, currency, tax category
- Shipping context: Product has weight, dimensions, shipping class, hazmat classification
These aren't different views of the same model. They're different models that happen to share a name. Trying to build one Product class that satisfies all contexts creates a bloated, incoherent model that nobody understands.
Finding Boundaries: Event Storming
Event storming is the most practical technique for identifying bounded context boundaries. You map out domain events (things that happen) on a timeline, then look for clusters.
Process:
- Write domain events on sticky notes (orange):
OrderPlaced,PaymentReceived,InventoryReserved,ShipmentDispatched - Arrange them chronologically
- Identify commands that trigger events (blue):
PlaceOrder,ProcessPayment - Identify aggregates that handle commands (yellow):
Order,Payment,Shipment - Draw boundaries around clusters where the language and actors change
The boundaries emerge where different actors (customer vs warehouse staff vs finance team), different language (order vs shipment vs payment), and different rates of change (catalog changes daily, payment logic changes quarterly) meet.
Context Mapping Patterns
Once you have bounded contexts, you need to define how they interact. Context mapping describes the relationships between contexts.
Shared Kernel
Two contexts share a small subset of the model. Changes to the shared part require coordination between both teams.
When to use: When two contexts genuinely share a core concept that should stay in sync. Keep the kernel as small as possible — shared kernels create coupling.
Anti-Corruption Layer (ACL)
Advanced System Design Cohort
We build this end-to-end in the cohort.
Live sessions, real systems, your questions answered in real time. Next cohort starts 2nd July 2026 — 20 seats.
Reserve your spot →A translation layer that prevents one context's model from leaking into another. The downstream context defines an interface in its own language and translates the upstream's model.
When to use: When integrating with legacy systems, third-party APIs, or any upstream context whose model you don't control and don't want to adopt.
Open Host Service
A context provides a well-defined API for other contexts to consume. The API uses a published language (documented protocol) that doesn't expose internal implementation details.
Customer-Supplier
The upstream context (supplier) provides what the downstream context (customer) needs. The customer can influence the supplier's API, but the supplier has the final say.
Typical in practice: The orders team (customer) needs specific data from the catalog team (supplier). They negotiate the API, but the catalog team controls the implementation.
Bounded Contexts and Microservice Boundaries
A common mistake: equating bounded contexts with microservices 1:1. This often creates services that are too small, leading to distributed monolith problems.
Guidelines:
- One microservice should not span multiple bounded contexts. This recreates the monolith with network calls.
- One bounded context can contain multiple microservices if the context is large and has clear internal subdivisions.
- Start with one service per bounded context. Split only when scaling, team autonomy, or deployment needs require it.
Real Example: Fintech Domain
Consider a fintech application. Event storming reveals these contexts:
Notice: "Account" means different things in Onboarding (application status, identity verification) vs Accounts (balance, statements) vs Ledger (double-entry journals). Three different models behind one word.
The context mapping:
- Onboarding → Regulatory Reporting: Customer/Supplier. Regulatory needs onboarding data for compliance.
- Accounts ↔ Ledger: Shared Kernel for the
Moneyvalue object. Both need consistent currency math. - Transactions → Payments Gateway: ACL. The transactions context defines its own payment model; the ACL translates to the specific payment processor's API.
- Transactions: Open Host Service. Published API for other contexts to initiate and query transactions.
Common Mistakes
-
Drawing boundaries around entities instead of behavior. A "Product Context" and a "Customer Context" sound right but often create anemic contexts with no business logic. Draw boundaries around business capabilities ("Pricing", "Fulfillment", "Risk Assessment").
-
Forcing a universal data model. If two teams argue about what fields belong on a model, they're probably in different bounded contexts. Let each context have its own model.
-
Ignoring team structure. Conway's Law is real. If two contexts are owned by the same team, the boundary will erode. Align context boundaries with team boundaries.
-
Over-modeling too early. You don't need to identify every bounded context on day one. Start with the obvious ones and refine as you learn more about the domain. Event storming is iterative.
Bounded contexts aren't a technical decision — they're a domain modeling decision. Get the boundaries right, and the technical implementation (monolith, microservices, modular monolith) follows naturally. Get them wrong, and no amount of technical sophistication will save you from a tangled domain model.
More in Architecture
The Strangler Fig Pattern: Migrating Legacy Systems Incrementally
Implementing the strangler fig pattern for legacy migration with request routing, data synchronization, feature parity verification, and a realistic migration timeline.
Designing Data Pipeline Architecture for Real-Time Analytics
Real-time data pipeline design covering Lambda vs Kappa architecture, stream processing with Kafka Streams and Flink, and handling late-arriving data.