Skip to content
Domain-Driven Design: Drawing the Right Service Boundaries 4 min

Domain-Driven Design: Drawing the Right Service Boundaries

SD
ScaleDojo
May 11, 2026
4 min read933 words
Domain-Driven Design: Drawing the Right Service Boundaries

How Twitter's 'Order' Became Three Different Things

In 2013, Twitter's ads platform had a problem. The word 'campaign' meant something different to every team. For the sales team, a campaign was a deal with a budget and schedule. For the ad-serving team, it was a targeting ruleset. For the billing team, it was a revenue line item. They had one Campaign table trying to serve all three, and every schema change required coordinating 4 teams. The codebase was littered with if-statements checking which 'type' of campaign it was. When they finally applied DDD principles and split into bounded contexts - each with its own Campaign model - deploy velocity tripled. This is the core insight of Domain-Driven Design: the same word often means fundamentally different things in different parts of your business, and forcing a single model creates distributed monoliths.

Bounded Contexts: The Core Concept

The Same Word, Different Meanings:

E-Commerce Example - What is an 'Order'?

  Shopping Context:        Fulfillment Context:     Billing Context:
  +------------------+     +------------------+     +------------------+
  | Order            |     | Order            |     | Order            |
  | - cart_items[]   |     | - shipment_id    |     | - invoice_id     |
  | - coupon_code    |     | - warehouse      |     | - total_amount   |
  | - shipping_addr  |     | - tracking_num   |     | - payment_method |
  | - estimated_cost |     | - weight_kg      |     | - tax_amount     |
  | - customer_id    |     | - carrier        |     | - refund_status  |
  +------------------+     +------------------+     +------------------+
       |                        |                        |
  Cares about:             Cares about:             Cares about:
  What did they buy?       How do we ship it?       How do we charge?

  WRONG: One giant Order table with 40 columns serving all teams.
  RIGHT: Three separate Order models, each with only its own fields.
         Linked by order_id but completely independent schemas.

Context Mapping: How Contexts Relate

Context Map (relationships between bounded contexts):

  [Shopping Context]          [Fulfillment Context]
        |                            |
        |--OrderPlaced event-------->|  (Async event)
        |                            |
        |                      [Billing Context]
        |                            |
        |--OrderPlaced event-------->|  (Async event)

Relationship Patterns:

  Pattern           Description                     Example
  ----------------  ----------------------------    ----------------
  Shared Kernel     Two contexts share a small      User ID format
                    piece of model (risky!)         shared by all

  Customer-Supplier One context provides data       Catalog -> Search
                    another consumes (upstream/     (Catalog is upstream,
                    downstream)                     Search is downstream)

  Anti-Corruption   Downstream builds a translation Legacy billing API
  Layer (ACL)       layer to protect its model      wrapped in clean
                    from upstream's model           interface

  Published         Upstream publishes formal API   Public REST API
  Language          that all downstreams consume    with versioning

  Conformist        Downstream accepts upstream's   Using Stripe's
                    model as-is (no translation)    data model directly

Finding the Right Boundaries

Four Signals That Reveal Boundaries:

  1. LANGUAGE DIVERGENCE
     When teams use the same word differently, you found a boundary.
     'Customer' to Sales = lead with budget
     'Customer' to Support = ticket history
     'Customer' to Billing = payment profile
     --> Three bounded contexts.

  2. ORGANIZATIONAL STRUCTURE (Conway's Law)
     Your architecture will mirror your team structure.
     Team A owns Users --> User Service
     Team B owns Orders --> Order Service
     Team C owns Payments --> Payment Service
     Fighting Conway's Law rarely works.

  3. RATE OF CHANGE
     Pricing rules change weekly.
     User registration changes yearly.
     --> Separate them so pricing deploys don't risk auth bugs.

  4. DATA OWNERSHIP
     Ask: 'Who is the single source of truth for this data?'
     User profile? --> User Service owns it.
     Order status? --> Order Service owns it.
     If two services both 'own' the same data, your boundaries are wrong.

Common Boundary Mistakes

Anti-Pattern: Distributed Monolith

  Symptom: Every request touches 5+ services.

  [Service A] --> [Service B] --> [Service C] --> [Service D]
       \                                            /
        \--------> [Service E] ---> [Service F] ---/

  Cause: Services split by TECHNICAL layer (API, logic, data)
         instead of by BUSINESS capability.

  WRONG Split (by layer):          RIGHT Split (by capability):
  +-------------------+            +-------------------+
  | API Service       |            | User Service      |
  | (all endpoints)   |            | (signup, profile, |
  +-------------------+            |  auth, settings)  |
  | Business Logic    |            +-------------------+
  | Service           |            | Order Service     |
  +-------------------+            | (cart, checkout,   |
  | Data Service      |            |  order history)   |
  | (all DB access)   |            +-------------------+
  +-------------------+            | Payment Service   |
  Every request goes               | (charge, refund,  |
  through all 3!                   |  invoices)        |
  (Distributed monolith)           +-------------------+
                                   Each handles full request
                                   independently.

The Ubiquitous Language

Within each bounded context, everyone - developers, product managers, domain experts - uses the same terminology. If the billing team says 'invoice' and the shipping team says 'packing slip,' those are different concepts in different contexts. Do not force them into a shared model. The code should use the exact words the business uses: no 'AbstractPaymentProcessorFactory' when the business says 'charge the customer.'

Domain-Driven Design: Drawing the Right Service Boundaries - Architecture Diagram
Architecture overview

Interview Tip

DDD questions are really about service decomposition. When asked 'How would you split this monolith into microservices?', use bounded contexts: (1) Identify where the same word means different things to different teams - those are your context boundaries. (2) Check Conway's Law - align services with team ownership. (3) Verify each service can handle its common operations without calling other services. (4) Use events (not synchronous calls) between contexts. If you mention the Anti-Corruption Layer pattern when integrating with legacy systems, that shows real DDD depth. The biggest red flag is splitting by technical layer (API/Logic/Data) instead of business capability.

Key Takeaway

DDD's bounded contexts tell you where to draw service boundaries: around distinct business capabilities with their own data, language, and models. Look for language divergence (same word, different meanings), organizational boundaries (Conway's Law), different rates of change, and clear data ownership. Services that share too much data or vocabulary are probably one bounded context incorrectly split. Split by business capability, not technical layer, to avoid distributed monoliths.

Enjoyed this article?

Share it with your network to help others level up their system design skills.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!

Related Articles

Enjoyed this content?

Your support keeps us creating free resources

We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.

$

One-time payment via Stripe. ScaleDojo account required.

ScaleDojo Logo
Initializing ScaleDojo