Ch. 10 · Microservices

Microservices Event Sourcing

Store events as the source of truth, rebuild state by replay, and manage versioning with snapshots.

~2 min readadvancedupdated Oct 5, 2026

In event sourcing the append-only log of events is the source of truth, and current state is a projection built by replaying those events. It gives a complete audit trail and lets you derive new views from history, at the cost of more complexity in reads and versioning.

Before you start

You should understand events, state and CQRS. This article covers the model and its trade-offs.

Step-by-step walkthrough

Step 1: Append events, never update

Every change is a new event appended to a stream, such as OrderPlaced or ItemShipped. Nothing is overwritten, so the history is intact and the events are facts about what happened. The log is the durable record.

Step 2: Derive state by replay

Current state is a fold over the events: start empty and apply each event in order. This makes any past state reconstructable and lets you add a new read model later by replaying from the beginning, which is impossible with mutable rows.

Step 3: Version events and snapshot long streams

Events are a public contract, so evolve them additively and version the schema. Replaying a very long stream on every read is slow, so store periodic snapshots of the state and replay only the events after the snapshot. This bounds read cost.

Worked scenario

State is computed by applying events in order.

events: OrderPlaced(total=50), ItemShipped(item=A), ItemShipped(item=B)
state:  apply in order -> { total: 50, shipped: [A, B] }
replay from snapshot@OrderPlaced -> only ship events re-applied
Text

Walk through the example

The state is a fold, so it can be rebuilt at any time and audited line by line. A snapshot at OrderPlaced means a read applies only the later events, keeping replay short. New projections can be added by replaying the full stream once.

Common mistake

Treating events as CRUD records and mutating them, which destroys the audit trail and the ability to replay. Another is ignoring schema versioning, so an old event cannot be read by new code.

Verify the behavior

Rebuild state from events and compare it with a snapshot plus incremental replay to confirm they match. Add a new read model and replay history to populate it. Read an old event with current code and confirm backward compatibility.

Interview exercise

Why are event-sourced systems well suited to adding new read models?

Answer and reasoning

Because the full history of changes is stored, a new projection can be built by replaying every event rather than needing a migration or backfill from current state, which may lack the detail. The events carry the facts needed to compute any derived view, so the read side can evolve independently as long as the events are preserved.

Continue learning

Compare read models in Read models and the outbox in Outbox pattern. Read the microservices.io event sourcing pattern and try the Microservices interview questions.

More in Microservices

read ✓Microservices · hard

Microservices Anti-Corruption Layer

Protect a service's domain model from a foreign or legacy model with a translation layer at the boundary.

~2 min readread →
read ✓Microservices · hard

Microservices API Versioning and Evolution

Evolve service APIs without breaking consumers using additive changes, explicit versioning and consumer-driven contracts.

~2 min readread →
read ✓Microservices · hard

Microservices Backend for Frontend

Use a per-client BFF to aggregate services and shape responses, without letting it become a shared god service.

~2 min readread →
esc