Skip to main content

Bounded Contexts: The Foundation of DDD

Bounded Contexts are the most important concept in Domain-Driven Design. They define explicit boundaries within which a domain model applies. Without clear boundaries, you get the "Big Ball of Mud" - a tangled mess where everything depends on everything.

TL;DR

ConceptDefinition
Bounded ContextA boundary within which a particular domain model is defined and applicable
Why it mattersPrevents model pollution, enables team autonomy, clarifies ownership
Key insightThe same word can mean different things in different contexts

The Problem: Ambiguous Models

Consider a simple word: "Customer"

In a typical enterprise, "Customer" means different things to different teams:

What goes wrong:

  • Sales adds LeadScore, SalesRep, Pipeline
  • Support adds TicketHistory, SatisfactionScore, PreferredChannel
  • Billing adds PaymentMethod, CreditLimit, InvoiceAddress
  • Shipping adds ShippingPreference, DeliveryInstructions

Result: A God Object with 500+ fields that everyone depends on and no one owns.

The Solution: Explicit Boundaries

Each context has its own Customer model with only the attributes it needs.

What Defines a Bounded Context?

1. Linguistic Boundary

The same term means different things:

TermSales ContextShipping Context
OrderA potential sale with negotiationA shipment request with tracking
ProductSKU with pricing tiersPhysical item with dimensions/weight
CustomerLead with revenue potentialDelivery recipient with address

2. Model Boundary

Different models for the same concept:

// Sales Context
interface Customer {
id: CustomerId;
name: string;
leadScore: number;
assignedRep: SalesRepId;
opportunities: Opportunity[];
}

// Shipping Context
interface Customer {
id: CustomerId;
name: string;
defaultAddress: Address;
deliveryPreferences: DeliveryPrefs;
// No leadScore - doesn't exist here
}

3. Team Boundary

Often aligns with team ownership:

┌─────────────────────────────────────────────────────────┐
│ Bounded Context ≈ Team Boundary (Conway's Law) │
├─────────────────────────────────────────────────────────┤
│ Sales Context → Sales Engineering Team │
│ Billing Context → Payments Team │
│ Shipping Context → Logistics Team │
│ Support Context → Customer Success Team │
└─────────────────────────────────────────────────────────┘

4. Technical Boundary

Can be (but doesn't have to be) a deployment boundary:

Boundary TypeExample
Separate serviceMicroservice per context
Module in monolithNamespace/package separation
SchemaSeparate database schemas
NoneLogical boundary only (early stage)

Context Boundaries in Code

Bad: Shared Entity Across Contexts

// ❌ One Product class used everywhere
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; } // Catalog
public decimal Price { get; set; } // Pricing
public int StockLevel { get; set; } // Inventory
public decimal Weight { get; set; } // Shipping
public string TaxCode { get; set; } // Billing
// 50 more fields...
}

Good: Context-Specific Models

// ✅ Catalog Context
namespace Catalog
{
public class Product
{
public ProductId Id { get; }
public string Name { get; }
public string Description { get; }
public List<CategoryId> Categories { get; }
}
}

// ✅ Inventory Context
namespace Inventory
{
public class StockItem
{
public ProductId ProductId { get; } // Reference, not full entity
public int QuantityOnHand { get; }
public int ReorderPoint { get; }
}
}

// ✅ Pricing Context
namespace Pricing
{
public class PricedProduct
{
public ProductId ProductId { get; }
public Money BasePrice { get; }
public List<PricingRule> Rules { get; }
}
}

Common Mistakes

Mistake 1: Database-Driven Boundaries

❌ "We have a Products table, so we have a Products context"
✅ "We have different teams with different needs for product data"

Mistake 2: Technical-Only Boundaries

❌ "Frontend context, Backend context, Database context"
✅ Boundaries based on business capabilities

Mistake 3: Too Granular

❌ One context per entity (Customer context, Order context, Product context)
✅ Contexts around cohesive business capabilities

Bounded Context Checklist

Before defining a bounded context, verify:

  • Clear language - Terms have unambiguous meaning within the boundary
  • Cohesive model - Entities and rules belong together
  • Single team - One team can own and evolve it
  • Minimal dependencies - Limited integration points with other contexts
  • Clear interfaces - Well-defined contracts at boundaries
  • Appropriate size - Not too big (God context) or too small (nano contexts)

Quick Reference Card

┌─────────────────────────────────────────────────────────┐
│ BOUNDED CONTEXT QUICK REFERENCE │
├─────────────────────────────────────────────────────────┤
│ Definition: │
│ Explicit boundary where a domain model applies │
│ │
│ Identifies by: │
│ • Linguistic boundaries (same word, different meaning)│
│ • Team ownership │
│ • Change patterns │
│ • Consistency requirements │
│ │
│ Size guidance: │
│ • One team can own it │
│ • 5-10 aggregates typical │
│ • Can deploy independently │
│ │
│ Anti-patterns: │
│ • God context (everything in one) │
│ • Nano contexts (one per entity) │
│ • Technical boundaries (frontend/backend) │
└─────────────────────────────────────────────────────────┘

Next Steps