Subdomains and Bounded Contexts in Domain-Driven Design
Dividing a Large Domain Into Parts That Can Be Understood Independently
The central challenge in a large domain is that it cannot be modelled as one unified system. Different parts of the business use the same words to mean different things.
Trying to capture everything in a single model produces something too complex to understand and too coupled to change. The solution is to divide the domain into parts with clear boundaries, where each part has its own consistent model and vocabulary.
The previous article introduced the core ideas behind domain-driven design: the importance of a shared language, the domain model as a reflection of business rules, and the distinction between strategic and tactical patterns. This article starts with the strategic patterns, using the same online learning platform as the running example.
The Problem With a Single Model
Consider how the word “course” is used across an online learning platform.
To a student browsing the catalog, a course has a title, a description, a list of topics, an instructor name, a rating, and a price. It is something to evaluate before enrolling.
To an instructor editing content, a course has a curriculum structure, individual lessons with video and text, assignments, and a publication status. It is something to build and maintain.
To the billing system, a course is a product with a price, a discount policy, and a line on an invoice. It is something to charge for.
These are not the same concept. If we model “course” as a single class that serves all three perspectives, we end up with curriculum and lessons that the billing system never touches, a discountPolicy that the content editor has no use for, and a publicationStatus that the billing system interprets differently than the catalog. A requirement comes in to change the pricing model and three unrelated places break. Every change for one part of the system risks breaking another.
The problem is not that the class is large. The problem is that one word is being asked to carry three different meanings simultaneously. A developer changing the pricing model has to understand the catalog and the content editor to know what else might break. A developer fixing a publication bug has to navigate billing logic to understand the class. Nobody owns it clearly, and every change carries the risk of breaking something it was never meant to touch.
Subdomains
A subdomain is a coherent part of the business with its own concepts, rules, and vocabulary. On the learning platform, the business involves creating and delivering courses, enrolling students, tracking their progress, assessing their work, issuing certificates, billing students, processing payments, and sending notifications. Each of these is a distinct area with its own logic.
DDD classifies subdomains into three types.
Core subdomains are the parts that differentiate the business from its competitors. On the learning platform, this is the learning experience: curriculum design, learning progression, assessments, and certification. This is what students pay for and what instructors build toward. It deserves the most careful modelling and the most investment in keeping the design accurate.
Supporting subdomains are specific to the business but not the source of competitive advantage. Enrollment is a good example. It has its own rules around access periods, prerequisites, and cohort scheduling, but it is not what makes the platform worth using. It exists to support the core.
Generic subdomains are solved problems with no meaningful variation between businesses. Payment processing, notifications, and user account management fall here. A competitor uses the same payment processor. Generic subdomains are strong candidates for off-the-shelf solutions rather than custom development.
The classification matters because it guides where you invest your design effort. The core subdomain deserves rich modelling, close collaboration with domain experts, and careful attention to the language. A generic subdomain does not.
Bounded Contexts
A bounded context is an explicit boundary within which a particular model applies and the language is consistent. Inside a bounded context, every term has exactly one meaning. Outside it, the same term may mean something entirely different.
The key word is explicit. A bounded context is not something that emerges naturally from the code. It is a deliberate decision. This is where this model lives, these are its responsibilities, and this is where its language is authoritative. It is a conceptual boundary first, not a microservice, a module, or a package. How it maps to code structure depends on the team, the technology, and the scale of the system.
On the learning platform, you might define a catalog context responsible for how courses are presented to prospective students, a content context responsible for how instructors build and manage course material, and a billing context responsible for pricing and invoicing. Inside the catalog context, “course” means one thing. Inside the billing context, it means another. Both are correct within their own boundary.
Problem Space and Solution Space
Subdomains and bounded contexts are related but distinct, and confusing them is one of the most common mistakes in applying DDD. The difference becomes clear when you consider the problem space and the solution space.
The problem space is the business as it exists: the activities it performs, the rules it operates under, and the language it uses. You do not design the problem space. You discover it by talking to domain experts and observing how the business works.
The solution space is the software you build to address the problem. This is where design decisions are made. You choose how to structure the model, where to draw boundaries, and how the parts communicate.
Subdomains belong to the problem space. They are parts of the business domain that exist whether or not you build software for them. Bounded contexts belong to the solution space. They are explicit boundaries you draw around a model in software, where a particular language is consistent and a particular set of rules applies.
This distinction matters because you cannot design your way out of the problem space. If the business genuinely uses “course” to mean three different things, that is a fact about the domain. What you can design is how your software responds to that fact.
The Same Word, Different Meanings
The “course” example illustrates why bounded contexts exist, but it is worth being specific about what changes across them.
In the course catalog context, a course is something a prospective student evaluates. It needs a compelling title and description, a visible instructor profile, a rating based on reviews, and a preview of what is covered. The rules here are about discoverability and presentation. Whether the course content is complete is not a concern of this context.
In the content management context, a course is something an instructor assembles. It has a curriculum of sections and lessons, each with video, reading material, or an exercise. A course in this context cannot be published without at least one lesson. The rules here are about structure and completeness.
In the billing context, a course is a product that can be priced and sold. It has a base price, optional discount policies, and appears as a line item on an invoice. Whether the course has good reviews or a complete curriculum is not relevant here. The rules here are about pricing and financial records.
None of these models is more correct than the others. Each is correct within its own context, and each would be wrong if applied outside it.
How Subdomains and Bounded Contexts Relate
Subdomains are discovered. Bounded contexts are designed. This is the most important distinction between the two.
When you talk to domain experts, observe workflows, and map out the business, you are discovering subdomains. When you decide where to draw the boundaries in your software and how to structure the models within those boundaries, you are designing bounded contexts.
The relationship between them is not fixed. A single subdomain can be split into multiple bounded contexts when different parts of it evolve at different rates or are owned by different teams. The enrollment subdomain might be split into a self-service enrollment context used by students and an administrative enrollment context used by staff, because the rules and workflows are different enough to justify separate models.
Multiple subdomains can share a bounded context when the integration cost of separating them outweighs the benefit. On the learning platform, learning progression and assessments are technically distinct subdomains, but they are so closely intertwined in the student experience that separating them into different contexts might create more complexity than it solves.
Neither of these arrangements is a compromise. They are intentional design decisions driven by model cohesion, team ownership, and the cost of integration between contexts.
What matters is not the ratio of subdomains to bounded contexts. What matters is that inside each bounded context the model is consistent, the language is unambiguous, and the responsibilities are clear.
What Comes Next
Defining bounded contexts answers the question of where models live. It raises a new question. How do those contexts communicate with each other? A student who completes a course in the learning context needs that completion to be recognised by the certification context. An enrollment created in the enrollment context needs to be visible to the billing context for invoicing.
The next article covers context mapping: the patterns for describing and managing the relationships between bounded contexts.
This article is part of the Domain-Driven Design series
- 1. What Is Domain-Driven Design?
- 2. Subdomains and Bounded Contexts in Domain-Driven Design