EventStorming — A Workshop for Finding the Model in the Business
In the previous chapter we said that deciding where to draw boundaries is the heart of strategic design. So how do you find those boundaries?
EventStorming, the subject of this chapter, is one tool for that. Invented by Alberto Brandolini, the official site defines it as "a flexible workshop format for collaborative exploration of complex business domains"1.
What the tool is for
EventStorming is not a design method. It is a device for getting the people who know the business and the people who write the code to stand at the same wall.
Normally the knowledge of the business lives in someone's head and developers receive it as a requirements document. Going through a document drops the "why." A practice like "Friday's shipments have an earlier cutoff" is written as "Friday closes at 15:00," and the reason (the carrier picks up earlier) never arrives. Implement it without the reason and, when the carrier changes, no one knows what to fix.
Talking while putting notes on a wall brings that "why" out on the spot. A business person moving a note and saying "ah, there's an exception here" is not something a requirements document produces.
Three granularities
Brandolini's book covers three forms with different purposes2.
| Granularity | What you look at | Participants |
|---|---|---|
| Big Picture | The flow of the whole business, and where the problems are | Business, development, and management together |
| Process Modeling | The detail of one business process; decisions and branches | The people who own that process, plus developers |
| Design-Level | The model for implementation; candidate aggregates | Mainly developers |
Start with Big Picture. Jump straight to Design-Level and you argue about implementation without a shared picture of the business, and later discover that the process you modeled belongs to a different system entirely.
Within this guide's scope, Big Picture and Design-Level are the ones that pay off. The first finds candidates for the boundaries from Chapter 5; the second finds candidates for the aggregates in Chapter 10.
The grammar of the notes
Color-coding is at the center of EventStorming. The table below lists the ones you use most; there are others for opportunities and value. But the grammar — writing events in the past tense — matters more than the colors themselves.
| Color | What it represents | How to write it |
|---|---|---|
| Orange | Domain event | A verb in the past tense. "Order was confirmed" |
| Blue | Command (intent, action) | Imperative. "Confirm the order" |
| Yellow (small) | Actor | A person, department, or team |
| Yellow (large) | Constraint | A rule of the business. "It cannot be changed after confirmation" |
| Purple | Policy | "Whenever X happens, we do Y" |
| Green | Read model | The information a decision needs |
| Pink (wide) | External system | A payment service, a carrier's API |
| Pink (hot) | Hotspot | A question, a disagreement, a mismatch in words |
The source is ddd-crew/eventstorming-glossary-cheat-sheet, which defines a domain event as "a verb at the past tense."
How the notes line up
The colors have rules about how they are arranged. Someone does something (actor → command), a result occurs (event), and that triggers the next step (policy → the next command) — a chain.
The solid arrows are the main chain; the dotted ones are supporting elements. This chain runs left to right across the wall in time order.
There are four rules for reading it.
| Rule | Content |
|---|---|
| Time flows left to right | Vertical position carries no meaning. Things that happen at once go in a column |
| There is always a reason between two events | If it happens automatically, a policy sits between them; if a person triggers it, a command and an actor do |
| Commands can fail; events cannot | "Confirm the order" can be rejected, but "the order was confirmed" is something that happened |
| A gap you cannot explain is a hotspot | Do not hide "I don't know what happens here" — leave it in hot pink |
The third rule is the one that pays off in code. The conditions under which a command fails become the business rules on the entity (Chapter 9). The constraint "an order with no lines cannot be confirmed" is written beside the blue note on the wall and becomes an exception inside Order::confirm() in code.
At the Big Picture stage, aggregates do not appear. You only lay out who did what and what happened. No note color corresponds to an aggregate at all; what the large yellow note stands for is the constraint. Candidate aggregates come into view once you have events that change together under one command, and that is Design-Level work (covered below).
Writing in the past tense leaves only what actually happened. "Confirm the order" describes a feature; "the order was confirmed" is an event in the business.
Write features and you get pulled toward the screens and operations of the existing system. The moment you write "press the confirm button," the design assumes a button exists. Write facts and you can decide later whether it happens automatically or someone triggers it.
Hotspots (hot pink) are easy to dismiss, but they are where boundary candidates surface most often. When participants disagree about what "product" refers to, two contexts are overlapping right there.
Running a Big Picture session
Brandolini's book breaks the Big Picture workshop into phases. The flow comes down to this.
From chaotic exploration to a timeline
In the first phase, participants post whatever events come to mind, out of order. Do not tidy the order yet. Try to fix the sequence first and the talking narrows to one person, and the events other participants know never come out.
Once everyone has finished posting, rearrange into a timeline. Duplicates surface here, and "we were calling the same thing by different names" comes into the open. For an e-commerce order, the line looks like this.
Order was confirmed → Stock was reserved → Payment completed → Shipment was requested → Goods were dispatched
During the rearranging, places where people disagree about the order appear. If the business people disagree about whether stock is reserved before or after payment, put a hotspot there. That disagreement feeds directly into a design decision — reserve stock first and you need a release path when payment fails; reserve it later and you need to void a payment when stock runs out.
How the notes map onto the design
This is the center of the chapter. The notes on the wall each correspond to something in the implementation.
| Note | Where it lands | Chapter |
|---|---|---|
| Orange (event) | Domain event | Chapter 12 |
| Blue (command) | The input to a use case | Chapter 15 |
| Purple (policy) | An event listener, or a domain service | Chapter 11 / Chapter 12 |
| Yellow (actor) | The subject of authorization | Chapter 22 |
| Pink (external system) | An anticorruption layer | Chapter 5 |
| Hot pink (hotspot) | A boundary candidate | Chapter 5 |
Most of the right-hand column is still ahead of you. We only show the correspondence here; what each one is gets covered with implementations in its own chapter.
Concretely, for the order example. Suppose the wall reads like this.
| Note | Content |
|---|---|
| Blue (command) | Confirm the order |
| Yellow (actor) | Buyer |
| Orange (event) | Order was confirmed |
| Purple (policy) | When the order is confirmed, reserve the stock |
| Orange (event) | Stock was reserved |
In implementation, that becomes:
// The blue note → the input to a use case
final class ConfirmOrderCommand
{
public function __construct(
public readonly int $orderId,
) {}
}
// The orange note → a domain event. The words on the note become the class name
final class OrderConfirmed
{
public function __construct(
public readonly OrderId $orderId,
public readonly DateTimeImmutable $occurredAt,
) {}
}
// The purple note → an event listener. "Whenever X, do Y" takes this shape directly
final class ReserveInventoryOnOrderConfirmed
{
public function handle(OrderConfirmed $event): void
{
// Reserving the stock. The implementation is covered in Chapters 11 and 12
}
}
The words on the note matching the class names is the ubiquitous language from Chapter 5. If what the business people call "the order was confirmed" is OrderConfirmed in the code, the specification discussion and the code discussion run on the same words.
Finding candidate aggregates
Go as far as Design-Level and candidate aggregates come into view. Events that change together under one command likely belong to the same aggregate.
If confirming an order raises both "order was confirmed" and "order lines were confirmed," the order and its lines are one aggregate. "Stock was reserved," on the other hand, can happen at a different moment and the business still works, so it belongs to another.
Chapter 10 covers that judgment in detail. What matters here is that the aggregate boundary comes out of observing a workshop rather than out of a desk exercise.
What sits between the notes and the aggregates
Seeing candidates and settling an aggregate are different things. EventStorming itself has deliberately dropped the word "aggregate" from its vocabulary. The large yellow note that used to be called an aggregate is now the constraint3. The method puts you at the same wall as the business people, so it keeps the design-side word out of the room.
The same sheet describes what a Big Picture session surfaces not as aggregates but as boundaries: "From a Big Picture EventStorming we can picture Emerging Bounded Contexts. They are the first indicators of where to start deep-diving towards designing bounded contexts around business problems." What comes off the Big Picture wall is a read on where the boundaries are, not a definition of an aggregate.
Designing the aggregate itself has its own tool. ddd-crew's Aggregate Design Canvas is a sheet that writes out a single aggregate across nine sections. Filling it in forces the question of where the boundary sits, which makes it a tool for testing a candidate. Three of those nine sections are the ones that check a boundary, and Chapter 10 covers them as the criteria this guide uses.
The tooling from workshop to implementation is laid out stage by stage in ddd-crew/ddd-starter-modelling-process, with a "start here" tool recommended at each stage. Its opening note says the process is for beginners and "is not a linear sequence of steps that you should standardise as a best practice." What is recommended is the tool at each stage, not the order they come in.
Drawing the business as a story
The sheets above are all tools for the stage where you design aggregates. For the stage where you learn the business, there are options beyond sticky notes too. Domain Storytelling draws it as a single story, in pictures and arrows.
The people and systems that take part are actors; the documents and things they pass around are work objects. Join the two with an arrow, label it with a verb, and you have a sentence; the number on the arrow gives the sentence its place in the order. "The cashier looks at the seating plan." "The cashier tells the moviegoer which seats are free." One sentence at a time. The point is that branches are not drawn first. You establish one typical thread, and only then collect what else could happen.
The two are not exclusive. The official Quick-Start Guide says you can carry the conversation on with EventStorming and other techniques once the stories are drawn.
Things to watch for
- Do not run it with developers only. Without the business people you just re-post the structure of the existing code on the wall. Nothing new surfaces
- Timebox it. A Big Picture session takes half a day to a full day. Starting with two hours and a narrow scope lasts better than doing the whole thing once
- Do not post CRUD. "Order was registered" and "order was updated" are not words from the business. Ask again what actually happened and they separate into "the order was confirmed" and "the delivery address was changed"
- Do not try to get the order right from the start. Skip chaotic exploration and only the loudest person's view ends up on the wall
For remote sessions, use an infinite canvas such as Miro or Mural. The count of notes runs into the hundreds, so screen space becomes the constraint.
Summary
| Point | Content |
|---|---|
| Purpose | Put the people who know the business and the people who write the code at the same wall. Recover the "why" a document drops |
| Granularity | Start with Big Picture. Design-Level comes just before implementation |
| Grammar | Events in the past tense. Writing facts matters more than the colors |
| Hotspots | Where the words disagree is a boundary candidate |
| Connection to design | Orange → domain event / blue → use case / purple → listener |
| Another notation | Domain Storytelling draws the business as a single story. Not exclusive — the two combine |
That completes strategic design. From the next chapter, we move into how to build what is inside the boundaries.
Further reading
- The EventStorming official site — the definition and workshop format from its inventor, Alberto Brandolini
- Alberto Brandolini, Introducing EventStorming (Leanpub) — the original source, covering Big Picture, Process Modeling, and Design-Level in separate chapters
- ddd-crew/eventstorming-glossary-cheat-sheet — the mapping between note colors and concepts
- ddd-crew/ddd-starter-modelling-process — the path from understanding the business to code, split into stages, with the tools recommended at each
- ddd-crew/aggregate-design-canvas — a sheet that writes out a single aggregate across nine sections
- Domain Storytelling — drawing the business as a single story in pictures; the notation is laid out in the Quick-Start Guide
- Masanobu Naruse, "Object Modeling with EventStorming" (Object-Oriented Conference 2024, in Japanese) — includes a live demonstration of a workshop