The Q&A guide to decode Event Modeling: the 3 system building blocks, the completeness check, the pure Command Handler — and 8 steps to get your team started.
Why this booklet
You join a team that talks about "slices," "Read Models," and "Information Completeness Checks." Your colleagues sketch orange and blue sticky notes on a Miro board and walk through the system from left to right. You have no framework to hook your understanding on.
This 72-page Q&A booklet answers exactly that. Martin Dilger — author of the 600-page Understanding Eventsourcing — extracted the 17 most common questions about Event Modeling, the visual design methodology that precedes and structures implementation. This is not a full tutorial and not the big book: it is a quick-start guide to decode your team's vocabulary and model your first flow on your own.
The ideas that stick
Five ideas worth carrying from this booklet — in the order they build on each other.
1Event Modeling solves a communication problem, not a technical one
Picture a project kick-off meeting. The developers talk about aggregates (clusters of related objects that change together as one unit) and APIs. The product owner talks about user journeys. The tester talks about use cases. Nobody is talking about the same thing.
Event Modeling answers this. The method produces a visual board — a sequence of sticky notes readable left to right — that developers, testers, and business stakeholders can all read without prior training. Dilger puts it this way: "a universal language that describes requirements so clearly and precisely that both business stakeholders and developers can fully grasp what needs to be built." (ch. 2)
Why it works: every box on the board is either a concrete fact that happened in the system (an event, past tense and immutable) or an intention (a command). Facts and intentions are understandable by everyone, unlike technical abstractions. The board is the shared language, and shared language is precisely what has been missing in most IT projects.
One important thing to know up front: Event Modeling does not require Event Sourcing. Dilger is explicit: "The answer is a clear no." (ch. 4) Event Sourcing is just one possible way to implement a system modeled with Event Modeling. You can apply the method to a legacy CRUD system, a SQL database, or anything else — the board describes information flow, not storage technology.
2Everything in the system is one of three slices
Here is the complete list of building blocks in Event Modeling. There are exactly three.
- State Change Slice — the only way to bring information into the system. A user clicks "Submit Order" → the command
PlaceOrderis sent → the eventOrderPlacedis recorded. Always in that order: Source → Command → Event. One command per slice, no exceptions. - State View Slice — the only way to get information out of the system. The event
OrderPlacedpopulates the read modelActiveOrders, which the "My Orders" screen then displays. Always: Event(s) → Read Model → Screen/Automation. - Third Party Integration (the gear symbol = Automation) — a call to an external system. The HTTP call lives inside the gear; the business logic stays in the Command Handler.
A note on the Third Party Integration that surprises most people: when you model an external API call (say, a payment gateway), the gear calls the external API — but the command it issues is for your system only. The command ConfirmPayment is not "call Stripe." It is "record that payment has been confirmed," with the result from Stripe already in the command payload. Your business logic stays pure; the external call stays in the infrastructure.
Full flow, Stripe as the example.
- State Change. Screen →
SubmitPaymentcommand →PaymentSubmittedevent. Intent recorded. No Stripe call yet: your system has only noted that a payment was requested. - Automation triggered.
PaymentSubmittedwakes up the Process Manager. The PM owns all the infrastructure: it calls the Stripe HTTP endpoint, handles timeouts, and tracks attempt count in its own replayed state (state rebuilt by re-applying its own past events in order — no database query, no external call). - Happy path. Stripe returns 200. The PM issues
ConfirmPayment { stripeChargeId, amount }. The Command Handler receives a command whose payload already contains the Stripe result. It emitsPaymentConfirmed. Business logic never touched Stripe. - Retry path. Stripe times out. The PM retries — and it knows how many attempts it has made because it stores that count in its own internal state, rebuilt on replay without re-calling Stripe. After three failures it issues
AbandonPayment→PaymentFailed→ compensating flow (a corrective sequence that undoes what earlier steps committed — cancel the order, notify the user, release any reserved stock).
Process Manager or Saga? For a single external integration, use a Process Manager: one stateful orchestrator (stateful: it keeps internal state rebuilt via event replay, so it always knows where it left off) that owns the Stripe call, owns the retry logic, and replays cleanly without re-triggering side effects. A Saga — a choreography-based pattern where each service reacts to events and acts independently, without a central controller — fits better when multiple independent services must coordinate across bounded contexts (distinct sub-systems with their own data model and vocabulary, like Billing and Shipping) — a hotel-booking service and a rental-car service each reacting to the same event without calling each other. One external API: one PM. Multiple services: choreography (no central coordinator — each service listens for the relevant event and acts on its own).
3The Information Completeness Check: no assumption left invisible
The classic scenario: you model a read model "Available Balance" that shows amount – holds. In implementation, you discover that holds is never stored in any event. Two weeks of rework. Dilger: "A major reason software projects get delayed is due to incorrect assumptions about data." (ch. 5)
The Information Completeness Check forces you to verify, for every single attribute in a read model, that the value comes explicitly from a connected event. No arrow = no data = red. Implementation cannot begin until everything is green. The rule applies to all elements: commands, screens, automations — every attribute must be traceable to a source.
discountCode has no source event — the arrow is red, implementation is blocked until the data origin is defined.Before reading on: why does it matter whether the source is made explicit at modeling time rather than at implementation time? Think about this — then read on. Because the later you find the missing data, the more expensive the fix: a modeling-time discovery takes minutes to resolve; a discovery during a sprint review costs a rewrite of the event schema, the projector, and possibly the UI.
4Aggregate boundaries and the pure Command Handler
Two rules that look separate but share the same root: keep the domain pure.
On aggregates: "An aggregate is a consistency boundary." (ch. 10) When a command touches two aggregates at once, it usually means the boundaries are wrong — not that the command is wrong. Dilger's test: do these two things really need to be consistent at the same moment? If you book a hotel and a rental car, does the car need to be confirmed atomically with the hotel? Almost certainly not. Book the hotel, then book the car; if the car is unavailable, cancel the hotel. Two eventually consistent operations. "There is no atomic operation that deposits money in one account and withdraws it in another. It's two eventually consistent operations." (ch. 10)
On the Command Handler: a Command Handler takes a list of past events plus one command and returns a list of new events. Nothing else. "No external dependencies, no Event Store." (ch. 6) No HTTP calls. No database reads. No mocks needed to test it. "To test a Command Handler, you ideally don't need to mock anything." (ch. 6) The test pattern is always GIVEN (past events = current state) / WHEN (command) / THEN (new events). A pure function, fully deterministic, testable in complete isolation.
The Read Model is the mirror image. It takes events and returns a projection — a computed view derived purely from past events — with no command, because a Read Model decides nothing. It observes and renders. Testing it uses GIVEN (events) / THEN (read model state). No WHEN.
The symmetry in one line:
| Input | Output | |
|---|---|---|
| Command Handler | state (rebuilt from past events) + intent | new events |
| Read Model | events | readable view |
One writes history. The other reads it.
5Getting started in 8 steps — one workshop, one flow ready to implement
Dilger's 8-step onboarding for a team new to Event Modeling:
- EM introduction — one person with experience explains the method (30 min).
- Event brainstorm — everyone together lists all events in the system. More people = better. This is the chaotic phase; imperfection is fine.
- Storyboard — put the events in order. Find the "story" of the system, left to right.
- Group events — identify the first clusters. Doesn't need to be perfect; it will evolve.
- Add screens — make it visual, give the events a context.
- Add commands, read models, automations — on one group at a time, not the whole model.
- Define swimlanes — the first conversation about system boundaries and sub-domain ownership.
- Model slices in detail — full attributes, Given/When/Thens written, Information Completeness Check green.
"One well-executed slice is more valuable than four half-finished ones." (ch. 16) After step 8, the model should be detailed enough to be implemented by anyone on the team without asking for explanation.
Dilger also maps slices to Jira: one slice = one ticket, one chapter (a blue arrow grouping several slices) = one epic. Slice states move through Created → Planned → Assigned → Review → Done. Any change to a "Done" slice is treated as a new slice — it resets to Created and goes through the cycle again.
Three things I didn't know
- Event Modeling is fully technology-neutral in its initial phase. You can model a legacy system with traditional SQL tables, a NoSQL database, or a CQRS/ES stack (Command Query Responsibility Segregation / Event Sourcing: writes flow through commands and events, reads flow through separate projections) — the board describes information flow, not storage. Dilger documents this explicitly; most introductions to the method silently assume Event Sourcing.
- The "pure Command Handler" rule (no external dependencies, testable without mocks) is not just a code style — it is the formal guarantee that all business logic lives in the domain. The moment a Command Handler calls a service, business rules start leaking into the infrastructure, and the Given/When/Then contract breaks.
- A Read Model should not be designed to be reusable across many screens. Dilger's rule of thumb: one dedicated Read Model per UI component. A shared "CustomerStatus" read model that many slices consume sounds practical but leaks implementation details into the model and erodes its clarity over time.
My honest take
Dilger knows his subject. The Information Completeness Check alone justifies reading this booklet — it formalizes something every modeling workshop stumbles on informally: someone draws a read model, someone asks "but where does this field come from?", and nobody knows. Making that question a first-class constraint that blocks implementation is a simple and powerful idea.
The booklet is honest about its limits: it points back to the big book (600 pages) for everything about implementation. What it gives in 72 pages is enough to follow a team conversation, run a first workshop, and understand why your colleagues debate aggregate boundaries the way they do.
Two caveats to be clear about. First: roughly 15% of the content is commercial — the Nebulit Miro toolkit, the Accelerate consulting program, calls to contact Martin. It is not hidden, but it is there. Second: Event Modeling is a visual method. The PDF format loses half its substance — the Miro board screenshots, the color-coded swimlanes, the arrows. If you can, find an example board to look at alongside the text.
Odilon
Still relevant in 2026?
Very much so — the book was published in January 2025. Event Modeling as a design methodology continues to gain ground alongside the rise of event-driven architectures. One angle that has added relevance since: AI agents consume event streams and read models the same way human developers do, with the same need for well-named, self-describing flows. A clean event language built with Event Modeling is as useful to a language model generating code as it is to a developer reading a stream.
For whom?
Read it if
- You are joining a team that practices Event Modeling and want to decode the vocabulary in two hours
- Your team is considering adopting EM and you want a short introduction to share with everyone
- You know Event Sourcing implementation but not the visual design methodology that goes with it
- You have read Exploring CQRS and Event Sourcing and want the modeling-first perspective
Skip it if
- You need an implementation guide (event versioning, projections, Event Store setup) — read Understanding Eventsourcing directly
- You have already worked in Event Modeling with an experienced team — nothing new here
- You do not have access to Miro or an equivalent visual tool — the method is hard to practice without a collaborative board
Going further
This booklet covers Event Modeling — the design phase. For the implementation layer it points to, Exploring CQRS and Event Sourcing (Microsoft P&P, free PDF) covers CQRS, Event Sourcing, Process Managers and Sagas on a real project, with the honest trade-offs and the hard-won lessons. The DDD context that frames when to apply Event Sourcing at all is in Learning Domain-Driven Design (Khononov). For the full 600-page treatment of Event Sourcing implementation — versioning, projections, streams design — Dilger's own Understanding Eventsourcing (Leanpub) is the only book that covers it end to end.
Comments (0)