
Created on: 9/5/2025
Updated on: 9/21/2025
4 mins
Tactical Design with Domain Events
In our last article we explored aggregates — the building blocks that protect business rules and keep models
consistent.
But sometimes, enforcing rules inside a single aggregate is not enough. Actions often have ripple effects across the
system.
This is where Domain Events come in.
They let us capture what happened in the business domain and communicate it clearly across different parts of the
system.
Designing Domain Events
A domain event represents something meaningful that has occurred in the business.
It should be named in the past tense, reflecting the fact that it has already happened.
Examples:
OrderPlaced
PaymentConfirmed
ShipmentDispatched
When designing domain events:
- Focus on business meaning, not technical detail.
- Keep the event data minimal — just enough for other parts of the system to react.
- Express them in the ubiquitous language so they are instantly understandable to domain experts.
Implementing Domain Events
Domain events are typically raised inside aggregates when important business rules are applied.
For example, when an Order
transitions to the “paid” state, it might publish an OrderPaid
event.
How these events are handled depends on the architecture:
- Within the same bounded context, they may trigger changes in other aggregates.
- Across contexts, they are often published over messaging systems so other teams can react asynchronously.
The key point: events decouple producers from consumers. The order aggregate doesn’t need to know what Shipping or Billing will do with the event — only that the business has declared “Order Paid.”
Using Domain Events
Domain events open up several practical possibilities:
- Integration – Other contexts can subscribe to events to keep their models in sync (e.g., Shipping reacts to
OrderPlaced
). - Audit Trails – Events form a natural log of what happened, useful for compliance or debugging.
- Reactive Workflows – Complex processes can be modeled as chains of events instead of tightly coupled calls.
By building around domain events, systems become more modular, scalable, and adaptable to change.
Event Sourcing: Taking Events Further
Domain events can be stored just as messages, but they can also become the primary source of truth.
This is the idea behind Event Sourcing.
Instead of persisting the current state of an aggregate (for example, saving an Order
row in a database), we persist
the sequence of events that led to that state.
To reconstruct the current state, we replay all events in order.
Benefits of event sourcing:
- Perfect audit log of everything that ever happened.
- Ability to rebuild state in new ways (e.g., generating reports from raw events).
- Naturally aligned with the language of the business.
Challenges of event sourcing:
- More complex to implement and reason about.
- Requires careful handling of event versioning and evolving schemas.
- Not always necessary — often plain domain events with state stored in a database are enough.
Event sourcing is powerful, but it should be applied deliberately. It shines in domains where history matters just as much as current state, such as finance or logistics.
Closing Thoughts
Domain events extend the tactical toolbox of Domain-Driven Design.
They let us capture meaningful business facts, decouple systems, and design workflows that reflect reality more closely.
And for cases where history and traceability are critical, event sourcing takes this idea further — making events the very foundation of state.
Together with aggregates and value objects, domain events complete the picture of tactical design.
They remind us that software is not just about storing data, but about telling the story of what really happens in the
business.