(This was Issue #9 of my weekly Eventmodeling / Evensourcing Newsletter)
Before you dive into this topic - there is a new Online Course âImplementing Eventsourcingâ, that will guide you step by step through this process. Find more details at the end of this article.
We all know TODO Lists all too well. And most of use use them in one way or the other. One repeating TODO for me every saturday and sunday - get on a 10 km run (the photo shows the last one)
Speaking of TODO lists, I recently came across a LinkedIn post by Yves Goeleven discussing the age-old debate between Choreography and Orchestration in distributed systems. It sparked the usual discussions about which approach is better. My short answer? How about neither? (more on that later..)
This post reminded me that many people arenât familiar with a third, simpler alternative: the TODO List Pattern (and yes, you can argue that TODO Lists are a kind of choreography.. and they are a kind of orchestration.. but I donât want to go into that discussion yet again.. it leads nowhere in my opinion).
Watch a quick video to that shows how it works in just a few minutes.
In any distributed systemâwhether itâs built with Microservices, Modules, a well-structured Monolith, or even a distributed Monolithâthereâs always a need for process coordination.
Take a simple example: your system submits orders, and those orders need to be paid.
In this scenario, two distinct contexts are involved in a single process that needs to be synchronized.
For example, if an order is placed in the Order Service but the payment fails, we cannot confirm the order.
This highlights a common challenge with such processes: who owns the responsibility for coordinating them?
Orchestration
Using Orchestration to coordinate this process centralizes the ownership of the process. For instance, the âOrder Serviceâ itself can manage the logic to update the order status based on payment notifications from the Payment Service.
Alternatively, you could use a dedicated service or deployable, such as an âOrder Process Manager.â This component handles all dependencies, including Inventory, Fulfillment, and Tracking.
The âOrder Process Managerâ is responsible for issuing commands like âIssue Paymentâ when an order is placed or âCancel Orderâ if the payment fails.
The benefit: In the beginning, this approach is easier to understand and makes debugging simpler when things go wrong.
The downside: Over time, it can become increasingly complex. As more business logic is introduced, different domains (e.g., Payment, Shipping, Fulfillment) can start leaking into the process, complicating its management.
Choreography
Choreography attempts to eliminate coupling by keeping processes isolated.
In this approach, the âOrder Serviceâ submits an order without needing to know who will handle it next. The only thing the Order Service is aware of is this:
- If a âPayment Issuedâ event is received for a submitted order, the order can be confirmed.
- If a âPayment Failedâ event is received for the same order, it needs to be canceled.
The Order Service doesnât concern itself with the source of these events.
The benefit: This approach is more decoupled, making it easier to extend or modify individual services.
The downside: Itâs harder to debug when things go wrong. For example, if an order remains stuck in the âsubmittedâ state, youâll need robust monitoring to pinpoint exactly why itâs stuck.
In many cases, the implementation involves some form of a Saga to track the process. However, Sagas come with their own challenges. They can grow increasingly complex and introduce parallel timelines, making it harder to reason about the system. Humans, after all, arenât great at thinking in parallel timelines.
Which one is best? You might enjoy diving into lengthy discussions about this topic (I know, I sometimes do!), but Iâve realized these debates often miss the point. Itâs not about finding the âperfectâ approach. Just pick one, start with it, and adapt as needed when it stops working.
But wait⌠thereâs a third option.
TODO Lists
The TODO List Pattern is simple and often my first choice.
When an order is placed, we use this information to build a TODO list of tasks to complete next. Instead of reacting immediately to an event like âOrder Submitted,â we construct a âPayments to Issueâ TODO list. This list can be persisted in a database or simply exist in memoryâthe implementation doesnât matter.
What does matter is that the TODO list serves as a clearly defined projection of state. The state of the system determines what adds to or removes items from the TODO list.
With this approach, we introduce a single automation process that has one responsibility: periodically checking if there are new TODO items in the list (e.g., payments to be issued). If new items are found, the automation processes themâfor example, by calling Stripe to issue a payment.
As with any TODO list, we need a way to check off completed items. This is where the connection between the âPayment Issuedâ event and the âPayments to Issueâ TODO list comes into play. Whenever a âPayment Issuedâ event is recorded, the corresponding TODO item is marked as resolved or removed from the list.
The automation only activates when new TODO items appear, ensuring efficiency and simplicity.
The biggest advantage of TODO lists is their simplicity and ease of debugging. You can easily visualize them on a debug page and check which TODO lists currently have open items.
Can you see how straightforward it is to model all steps using TODO lists? Take order confirmation as an example: When an order is placed, the TODO list creates an open item for the order that requires payment confirmation. Once the payment is confirmed, the corresponding TODO item is closed.
Itâs a simple, readable, and highly effective way to manage processes, isnât it?
If done right, the TODO List takes care of most logic for this small part of the system, leaving the automation (the gear symbol) as a simple Task Executor checking off TODOs.
By the way, there is a complete chapter about this Pattern in my Book âUnderstanding Eventsourcingâ.
Want to learn it faster in a practical way?
The Online Course âImplementing Eventsourcingâ gives you exactly that. Itâs a perfect companion to the Book âUnderstanding Eventsourcingâ!
Everything I know about Evenet Modeling & Event Sourcing in one course.
Martin Dilger
Join the Agentic Engineer Program
Apply Spec-Driven Development Hands-On - Event Modeling, Event Sourcing, and AI Engineering with autonomous agents.
Book a Call Today
Want to talk through how Event Modeling could work for your team or project? Letâs have a quick, no-pressure conversation.
