We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
6 system design questions lean on this idea. Each walks through the full answer.
System Design Masterclass · Distributed Systems Core
Free preview: the first 2 parts of this 9-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Distributed Systems Core
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
Open your bank statement. You don't see "Current balance: $2,847.32" with no further explanation. You see a list of transactions, every deposit, every withdrawal, every transfer, in chronological order. The balance is derived from that list. If you want to know your balance on March 15th, you replay transactions up to that date.
Your bank doesn't store your balance and update it. It stores events and computes the balance. This is event sourcing.
Most software systems do the opposite. They store the current state. "user.address = 123 Main St", and overwrite it when it changes. The previous address is gone. The history of changes is gone. If you need to know what the address was last Tuesday for a fraud investigation, you're out of luck (unless you happened to build an audit log separately).
Event sourcing flips this model. Instead of storing the current state, you store the sequence of events that led to the current state: "AddressChanged: 456 Oak Ave -> 123 Main St on 2024-03-15." The current state is derived by replaying all events from the beginning.
This sounds expensive and complicated. It is, in exchange for some extraordinarily powerful capabilities: complete audit trails, time travel (reconstruct any past state), event replay (rebuild read models from scratch), and the ability to derive unlimited projections from the same event stream. These capabilities are why event sourcing is used at companies handling billions in transactions, banks, payment processors, trading platforms.
Martin Fowler, Greg Young, and the Domain-Driven Design community have been advocating this pattern since the early 2000s. Today it's the foundation of systems at Goldman Sachs, Stripe, and any company where "what happened and when" is as important as "what is the current state."
In a traditional system, the database table IS the source of truth:
orders table:
| id | status | total | updated_at |
|----|-----------|--------|------------|
| 1 | shipped | 99.99 | 2024-03-15 |
In event sourcing, the event stream IS the source of truth:
events for order 1:
| seq | event | data | timestamp |
|-----|-----------------|-------------------------|------------|
| 1 | OrderCreated | { total: 99.99 } | 2024-03-10 |
| 2 | PaymentReceived | { amount: 99.99 } | 2024-03-10 |
| 3 | ItemShipped | { tracking: "UPS123" } | 2024-03-15 |
The current state ("status: shipped") is computed by replaying events 1, 2, 3 in order. But you can also compute the state at any point, after event 1, the order was "created." After event 2, it was "paid." After event 3, it was "shipped."
Three fundamental rules of event sourcing:
Events are immutable. Once written, an event is never modified or deleted. If an order is cancelled, you don't delete the "OrderCreated" event, you append an "OrderCancelled" event.
Events are the only source of truth. Any "current state" view (a database table, a cache, a search index) is derived from events. If the derived view disagrees with the events, the view is wrong and must be rebuilt.
Events are ordered. Within an aggregate (a single order, a single user account), events have a strict sequence. Event 3 happened after event 2. This ordering is essential for correct state reconstruction.
| Traditional CRUD | Event Sourcing |
|---|---|
| Store current state | Store events that led to current state |
| UPDATE overwrites previous value | APPEND new event (old events preserved) |
| History lost unless separately audited | Complete history is the primary data |
| One view of the data | Unlimited projections from events |
| Debugging: "what is the state?" | Debugging: "what happened?" |