Subdomains: Where to Invest Your Effort
Subdomains are natural divisions of your business domain. Understanding them helps you decide where to invest your best engineers, where to buy off-the-shelf, and where "good enough" is actually good enough.
TL;DR
| Subdomain Type | Definition | Strategy |
|---|---|---|
| Core | What makes you unique, your competitive advantage | Build, invest heavily, best engineers |
| Supporting | Necessary but not differentiating | Build or buy, adequate investment |
| Generic | Solved problems, commodity | Buy, outsource, use existing solutions |
The Investment Problem
Not all parts of your system deserve equal attention:
What goes wrong:
- Senior engineers building login pages (solved problem)
- Junior engineers on core business logic (competitive advantage)
- Custom-built email system (SendGrid exists)
- Everything gets the same architecture (overkill or underbuilt)
The Three Subdomain Types
Core Subdomain
Definition: The part of your business that provides competitive advantage. If you do this poorly, you lose to competitors.
Characteristics:
- High complexity
- Frequently changing
- Unique to your business
- Hard to copy
Strategy:
- Build in-house
- Assign best engineers
- Apply full DDD tactical patterns
- Invest in deep domain modeling
Examples by Industry:
| Company | Core Subdomain |
|---|---|
| Netflix | Recommendation algorithm |
| Uber | Matching drivers to riders, surge pricing |
| Stripe | Payment processing, fraud detection |
| Search ranking algorithm | |
| Airbnb | Trust & safety, pricing optimization |
Supporting Subdomain
Definition: Necessary for the business to function but doesn't provide competitive advantage. Important, but not what makes you special.
Characteristics:
- Medium complexity
- Changes less frequently
- Could be similar across companies
- Important but not differentiating
Strategy:
- Build if custom needs exist
- Buy if good solutions available
- Adequate (not excessive) investment
- Simpler patterns acceptable
Examples:
| Supporting Subdomain | Why It's Supporting |
|---|---|
| Order management | Necessary, but not unique |
| Customer support ticketing | Important, but commodity |
| Inventory tracking | Required, but standard problem |
| Reporting/analytics | Needed, but not competitive advantage |
Generic Subdomain
Definition: Solved problems that are the same across all businesses. No competitive advantage possible.
Characteristics:
- Well-understood problems
- Stable, rarely changes
- Same everywhere
- Many existing solutions
Strategy:
- Buy off-the-shelf
- Use SaaS
- Use open-source
- Don't reinvent
Examples:
| Generic Subdomain | Solution |
|---|---|
| Authentication | Auth0, Okta, Firebase Auth |
| Email sending | SendGrid, Mailgun, SES |
| Payment processing | Stripe, Braintree (unless you're Stripe!) |
| File storage | S3, Azure Blob |
| Logging | Datadog, Splunk, ELK |
Real-World Example: E-Commerce Platform
Investment Strategy:
| Subdomain | Investment | Team | Architecture |
|---|---|---|---|
| Dynamic Pricing | High | Senior ML + Domain experts | Full DDD, Event Sourcing |
| Recommendations | High | ML engineers | Complex, custom |
| Search Ranking | High | Search specialists | Custom, optimized |
| Order Management | Medium | Mid-level engineers | Standard patterns |
| Inventory | Medium | Mid-level engineers | CRUD + events |
| Authentication | Low | Use Auth0 | SaaS integration |
| Low | Use SendGrid | API calls |
Identifying Subdomain Types
Questions to Ask
Is it Core?
- Would competitors pay to know how you do this?
- Does doing this better directly increase revenue?
- Is this why customers choose you over competitors?
- Does this require deep domain expertise?
Is it Supporting?
- Is it necessary for the business to function?
- Could you describe it to another company in the same industry?
- Are there multiple reasonable ways to implement it?
- Does it support core activities without being core itself?
Is it Generic?
- Is this the same problem every company faces?
- Are there multiple commercial solutions available?
- Would building custom provide any advantage?
- Is the problem well-understood with standard solutions?
Decision Matrix
┌─────────────────────────────────────────────────────────┐
│ SUBDOMAIN CLASSIFICATION MATRIX │
├─────────────────────────────────────────────────────────┤
│ │
│ Competitive Advantage? │
│ YES ──────────────────────────────────► CORE │
│ │ │
│ NO │
│ │ │
│ ▼ │
│ Off-the-shelf solution exists? │
│ YES ──────────────────────────────────► GENERIC │
│ │ │
│ NO │
│ │ │
│ ▼ │
│ ────────────────────────────────────► SUPPORTING │
│ │
└─────────────────────────────────────────────────────────┘
Subdomain Evolution
Subdomains aren't static - they evolve over time:
Examples of Evolution:
| Then | Now | What Happened |
|---|---|---|
| Custom web server | Use Nginx/Apache | Web serving commoditized |
| Custom database | Use PostgreSQL/MySQL | Databases became generic |
| Custom auth | Use Auth0/Okta | Auth became generic |
| Custom ML infra | Use AWS SageMaker | ML platforms emerged |
Implication: Regularly reassess your subdomains. Yesterday's core might be today's generic.
Architecture by Subdomain
Different subdomains deserve different architectural approaches:
Core Subdomain Architecture
// Full DDD with rich domain model
namespace Pricing.Domain
{
public class PricingEngine : AggregateRoot
{
private readonly List<PricingRule> _rules;
private readonly DemandModel _demandModel;
public Price CalculateOptimalPrice(
Product product,
CustomerSegment segment,
MarketConditions conditions)
{
var basePrice = product.BasePrice;
var demandMultiplier = _demandModel.GetMultiplier(conditions);
var segmentAdjustment = GetSegmentAdjustment(segment);
var rules = _rules
.Where(r => r.AppliesTo(product, segment, conditions))
.OrderBy(r => r.Priority);
var price = basePrice;
foreach (var rule in rules)
{
price = rule.Apply(price, demandMultiplier, segmentAdjustment);
}
AddDomainEvent(new PriceCalculated(product.Id, price, conditions));
return price;
}
}
}
Supporting Subdomain Architecture
// Simpler approach - transaction script or basic patterns
namespace Orders.Application
{
public class OrderService
{
public async Task<Order> CreateOrder(CreateOrderRequest request)
{
var order = new Order
{
Id = Guid.NewGuid(),
CustomerId = request.CustomerId,
Items = request.Items.Select(i => new OrderItem
{
ProductId = i.ProductId,
Quantity = i.Quantity,
Price = i.Price
}).ToList(),
Status = OrderStatus.Pending,
CreatedAt = DateTime.UtcNow
};
await _orderRepository.Save(order);
await _eventBus.Publish(new OrderCreated(order.Id));
return order;
}
}
}
Generic Subdomain Architecture
// Just use the library/service
namespace Notifications.Infrastructure
{
public class EmailService
{
private readonly ISendGridClient _sendGrid;
public async Task SendEmail(EmailRequest request)
{
var message = new SendGridMessage
{
From = new EmailAddress(request.From),
Subject = request.Subject,
HtmlContent = request.Body
};
message.AddTo(request.To);
await _sendGrid.SendEmailAsync(message);
}
}
}
Team Allocation by Subdomain
┌─────────────────────────────────────────────────────────┐
│ TEAM ALLOCATION STRATEGY │
├─────────────────────────────────────────────────────────┤
│ │
│ CORE SUBDOMAIN │
│ ├── Staff/Principal engineers │
│ ├── Domain experts embedded │
│ ├── Dedicated team │
│ └── High autonomy │
│ │
│ SUPPORTING SUBDOMAIN │
│ ├── Senior engineers │
│ ├── Domain expert access (not embedded) │
│ ├── Shared team possible │
│ └── Standard processes │
│ │
│ GENERIC SUBDOMAIN │
│ ├── Any engineer level │
│ ├── Integration focus │
│ ├── Minimal custom code │
│ └── Follow vendor docs │
│ │
└─────────────────────────────────────────────────────────┘
Common Mistakes
Mistake 1: Treating Everything as Core
❌ "Authentication is critical, so it's core"
✅ "Authentication is critical but generic - use Auth0"
Critical ≠ Core. Core means competitive advantage.
Mistake 2: Building Generic Subdomains
❌ "Let's build our own email sending system"
✅ "Let's use SendGrid and focus on our pricing algorithm"
Mistake 3: Underinvesting in Core
❌ "Junior devs can handle the recommendation engine"
✅ "Our best engineers should own recommendations - it's our moat"
Mistake 4: Over-engineering Supporting
❌ "Let's apply full DDD with Event Sourcing to order management"
✅ "Simple CRUD with events is sufficient for orders"
Mistake 5: Static Classification
❌ "We classified subdomains 3 years ago, we're done"
✅ "Let's reassess - has anything become commoditized?"
Staff+ Interview Questions
Q: How do you decide what's a core subdomain?
A: I ask:
- Does this provide competitive advantage?
- Would competitors benefit from knowing how we do this?
- Does doing this better directly impact revenue/growth?
- Is this why customers choose us?
If yes to most, it's core. If it's necessary but not differentiating, it's supporting. If there are commodity solutions, it's generic.
Q: Should you always buy for generic subdomains?
A: Almost always, but consider:
- Integration complexity - Sometimes building a thin wrapper is easier
- Vendor lock-in - Evaluate switching costs
- Compliance requirements - Some industries restrict SaaS
- Scale economics - At massive scale, building might be cheaper
But default to buy. The opportunity cost of building generic solutions is high.
Q: How do subdomains relate to bounded contexts?
A: They're orthogonal concepts:
- Subdomain = Business capability classification (core/supporting/generic)
- Bounded Context = Model boundary
A core subdomain might have multiple bounded contexts. A bounded context might span supporting and generic subdomains (though this is a smell).
Quick Reference Card
┌─────────────────────────────────────────────────────────┐
│ SUBDOMAIN QUICK REFERENCE │
├─────────────────────────────────────────────────────────┤
│ │
│ CORE │
│ • Competitive advantage │
│ • Build in-house │
│ • Best engineers │
│ • Full DDD patterns │
│ │
│ SUPPORTING │
│ • Necessary, not differentiating │
│ • Build or buy │
│ • Adequate investment │
│ • Simpler patterns OK │
│ │
│ GENERIC │
│ • Solved problems │
│ • Buy/outsource │
│ • Minimal custom code │
│ • Use existing solutions │
│ │
│ Key Question: │
│ "Would doing this better give us competitive │
│ advantage over our rivals?" │
│ │
└─────────────────────────────────────────────────────────┘
Next Steps
- Context Mapping - How subdomains interact
- Strategic Decisions - Framework for architectural choices
- DDD in Microservices - Subdomain-based service boundaries