Event Sourcing is like Time traveling
I know we can travel back (we technically called it "reproducibility"), but can we travel to the future?
In most traditional systems, when data changes, we lose the past.
Whether you update your order status, adjust inventory, or revise user details, each new change overwrites the previous state. This means you can't see the history—only the current snapshot.
Event Sourcing changes this. It lets you time travel through your system's history and understand how and when it changed.
Practice makes perfect, and there’s no better way to get ready for interviews than by building the tools you use daily. CodeCrafters lets you create your own Docker, Git, Redis, and more.
Hands-on Projects + Practice = Job Offer
Sign up and get 40% off if you upgrade.
Thank you to our sponsors who keep this newsletter free!
What Is Event Sourcing?
Event Sourcing captures every change to the application state as an immutable event.
Unlike the typical approach, where changes overwrite data, Event Sourcing records each change as a separate log entry, allowing you to replay and reconstruct the system's state at any given moment in time—like rewinding and fast-forwarding through time.
For example, think about inventory tracking. Instead of updating the inventory count directly from 200 units to 197 units after an item is shipped, you add an event like "Items Shipped -3" to an Event Log. Each change leaves a breadcrumb, and these breadcrumbs collectively tell the story of how the inventory level evolved over time.
Key Concepts to Understand
To get the full value out of Event Sourcing, you need to understand four key terms:
Command: Represents an action that requests a change in the system. For example, "Create Order" or "Update Inventory." Commands express intent.
Event: The resulting record of a change that has happened, like "Order Created" or "Inventory Updated." It also records all relevant information needed to reconstruct the system's state. Events are facts and are immutable.
State: Represents the current condition of an entity, and it is the result of processing all relevant events. Think of it as the latest version of an order or account balance, reconstructed by replaying all events from the beginning.
Command-Event Separation: Commands represent intentions to change state, while events represent actual state changes. Commands are processed to generate events, which are then persisted.
Commands express intent, events record facts, and state is derived by replaying those events.
Remember when I mentioned immutable before? This means that from the 4 CRUD operations, you only have two of them; you can not use the destructive operations.
How It All Comes Together: A Practical Example
Let's walk through how Event Sourcing works in a practical scenario.
Command: Imagine you need to add inventory to your system. You start by issuing a command like "Add 200 units to Product A." This command represents your intent to change the system state.
Command-Event Separation: The command represents the intent to add inventory but doesn't change the state by itself. Instead, the command is processed, validated, and transformed into an event. This separation ensures that the intent and the actual change are clearly distinct.
Event: After processing the command, the system generates an event called "Items Received +200." This event is the factual record of the action. Events are immutable, meaning you cannot change them once they are recorded. The event gets added to the event log, preserving a precise sequence of actions like "Item Created," "Items Received +200," and "Items Shipped -3."
Event Log: The event log is the heart of Event Sourcing. It stores each event as it happened, creating a historical record of all changes. This log allows you to see what happened at each point in time, providing complete traceability.
State: The current state of the system is derived by replaying all the relevant events. To determine the current inventory count for Product A, you start from an initial state of 0, then replay "Items Received +200," followed by "Items Shipped -3." The current state becomes 197 units. The state represents the latest version of an entity and is always reconstructed by processing all past events.
The Read Problem in Event Sourcing
You may be thinking, “Hey, wait a second, wouldn't doing these calculations every single time to reconstruct the state be computationally expensive?” and you are 100% right. That is one of the primary challenges in Event Sourcing systems.
Reading data is typically straightforward in a traditional database system. When you query the database, it returns the current state of the data.
However, in an event-sourced system, the current state isn't directly stored. Instead, you must reconstruct the state by replaying all relevant events.
Imagine reading the entire bank account history to calculate the balance.
There are four main strategies to help with the “reading“ problem:
Snapshots: Snapshots provide a point-in-time view of an aggregate's state. Using snapshots, the system only needs to replay events that occurred after the snapshot, significantly reducing the computational load.
Projections: Projections create pre-computed views of the data optimized for specific read patterns. They're updated in real-time as new events occur, allowing for fast reads without replaying events.
Caching: Implementing caching strategies can help reduce the need to reconstruct the state from events for frequently accessed data.
CQRS (Command Query Responsibility Segregation): This pattern separates the read and write models. The write model uses Event Sourcing, while the read model can be optimized for queries, often using projections.
The Power of Stored Events: The Opportunity in Data
Stored events offer a full audit trail, showing each state's transition and cause. Replaying events to trace issues simplifies debugging.
I want to push this idea further: what happens when we combine Event Sourcing with AI?
It doesn’t just tell you where you’ve been; it can help you decide where to go next.
This combination could redefine how systems predict and optimize future outcomes.
The historical data also reveals business insights, like peak order times and reasons for frequent returns.
Imagine a system that records "what happened" and uses that knowledge to predict what might happen next and even prevent undesirable outcomes before they occur.
AI can look at all those past events and start making some pretty wild guesses about the future. For example:
Online shopping: The AI might say, "Hey, based on how this customer's been shopping, I think they're about to ghost us." That's your cue to maybe send them a sweet discount.
Money stuff: It could spot fishy transactions by seeing weird patterns in how money's moving around.
Machines acting up: In factories, it might notice if a machine's about to break down based on weird sensor readings.
Basically, when you mix AI with Event Sourcing, you're giving your system a brain that not only remembers everything but can also think ahead.
Challenges and Considerations
Like everything in the industry (as well as in life), Event Sourcing comes with challenges:
Storage Costs: As event logs grow, storage and management become more costly and complex, requiring efficient strategies.
Complexity: Replaying events to reconstruct states is powerful but computationally challenging, needing careful optimization in large systems.
Event Versioning: It is difficult to manage changes in event structures. Best practices, like maintaining backward compatibility or version adapters, can help.
Eventual Consistency: Event Sourcing often leads to eventual consistency across the system, which can introduce delays or require additional mechanisms to ensure consistency at critical moments.
Wrapping up
Event Sourcing changes how we think about state and system evolution—it's like giving your system a memory. But the real magic happens when you put that memory to work.
Imagine a future where your system doesn't just store what happened but actively guides your decision-making, helps you avoid pitfalls, and optimizes every aspect of your operations. That future isn't far off—and it can start with Event Sourcing.
Event Sourcing isn't just about storing history—it's about understanding it.
System Design Classroom is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.
Articles I enjoyed this week
Clean Code - 5 Tips on Writing Clean Tests by
System Design Interviews were HARD Until I Learned these 15 Tips by
Key concepts of System design 3: System Context by
How to implement a Circuit Breaker by
Thank you for reading System Design Classroom. If you like this post, share it with your friends!
The way you architect your data model is the most critical part of any system. There are many proven ways to do it, but I believe the best way is to use event sourcing.
Great article, Raul!
This is a wonderful explanation of Event Sourcing, Raul!
Also, thanks for the mention.