Microservices Event Sourcing

Traditional databases store the latest state and overwrite the past. A bank balance table says "500" and forgets how the account reached that number. Event sourcing stores every change as an immutable event and rebuilds the current state by replaying them. History becomes the source of truth.

Layman Explanation

A paper bank passbook lists every deposit and withdrawal. The balance is the sum of all lines. Nobody erases a line; a correction becomes a new line. Event sourcing treats data like that passbook.

State Storage vs Event Storage

STATE STORAGE                    EVENT STORAGE

Account 101                      Account 101
+-----------+                    1. AccountOpened      0
| balance:  |                    2. MoneyDeposited   +800
|   500     |                    3. MoneyWithdrawn   -200
+-----------+                    4. MoneyWithdrawn   -100
(history lost)                   Replay = 500 (history kept)

Core Concepts

Event

An event is a fact in past tense that already happened: OrderPlaced, ItemAdded, AddressChanged. Events never change after saving.

Event Store

The event store is an append-only database. Each entry holds an aggregate id, a sequence number, a timestamp, and the event data.

Aggregate Stream

All events for one aggregate, such as one order, form its stream. Replaying the stream in order produces the current state.

Projection

A projection reads events and builds a view for a specific need, such as a balance table or a monthly report. Projections pair naturally with CQRS read models.

How a Command Flows

Command: WithdrawMoney(101, 200)
   |
   v
Load events of account 101 --> replay --> balance 800
   |
   v
Rule check: 800 is at least 200 --> allowed
   |
   v
Append event: MoneyWithdrawn(200) --> publish to subscribers

The service validates the command against the rebuilt state, then appends one new event. Subscribers such as notification and reporting services react to it.

Snapshots

Replaying thousands of events on every request wastes time. A snapshot saves the computed state at a point, for example after every 100 events. Loading then starts from the latest snapshot and replays only newer events.

Benefits

  • Complete audit trail that answers who changed what and when.
  • Time travel: rebuild the state for any past moment to investigate issues.
  • New projections built later from the full history.
  • Natural fit for event-driven microservices, since every change already exists as an event.

Challenges

Changing Event Shapes

Old events live forever, so their format must remain readable. Teams version events and write upcasters that translate old versions into new ones during replay.

Learning Curve

Developers must think in events rather than rows. Querying the event store directly is awkward, so projections become necessary.

Privacy and Deletion

Immutable history clashes with erasure rules for personal data. Common solutions encrypt personal fields with a per-user key and delete the key on request, which makes the stored data unreadable.

Example: Shopping Cart

CartCreated
ItemAdded(book)
ItemAdded(pen)
ItemRemoved(pen)
CheckoutStarted

Replaying yields a cart holding one book at checkout. Analysts learn that the customer removed a pen, a detail that a state table would have lost.

Event Naming Tips

Name events after business facts in past tense, such as InvoicePaid rather than UpdateInvoice. Include only the data that describes the change. Clear names let business experts read the stream and confirm that it matches reality.

Key Takeaways

Event sourcing stores facts, not snapshots of state. Replay rebuilds the present, projections serve queries, and snapshots keep performance healthy. Use it where audit trails and history carry real business value.