Event Sourcing logo

Architecture & Methodology

Official site

Event Sourcing

Event Sourcing — persisting state as an immutable sequence of domain events that is both the source of truth and a full audit trail.

Overview

Event sourcing stores every fact that happened, not just the current state. The event stream is append-only and immutable — current state is a projection you can rebuild at any point. That guarantees a complete, replayable history by construction.

It transforms debugging and analytics: instead of reconstructing why a system reached a state, you read the log. Temporal queries, projections, and even new read models are cheap because the raw facts are all there.

The real engineering weight lands on event design and versioning — events are contracts that outlive their producers. I treat them with the same care as public APIs so the stream stays trustworthy for years.

The append-only log is the source of truth. No in-place updates, no deletes unless the business genuinely needs them — which means the system can always answer "what actually happened" and "what did we know when", property that CRUD stores simply cannot offer.

Projections turn raw events into useful read models. I keep projection logic explicit and idempotent so each can be rebuilt from the stream on demand — which doubles as the cheapest possible disaster recovery: rebuild everything from the events.

Events are contracts in the strongest sense. I give each event a name, a version, and a stable schema, and I write migration/upcast logic so old events remain readable forever. The stream is a database with an SLA measured in years, not sprints.

Aggregates rehydrate from their event history. Instead of loading a row, I replay the relevant events through the aggregate so its state and invariants are always consistent with everything that has happened — a natural fit beside DDD and CQRS.

Temporal features fall out almost for free once the events exist: point-in-time queries, audit trails, "why did this change", and analytics over historical state. Things that require elaborate ad-hoc tooling elsewhere are a simple query here.

The discipline is real, and I am clear about it: event sourcing is not free. Event schema management, snapshotting for hot aggregates, and the mental shift from state to fact are genuine costs. It pays off for money-moving, auditable, long-lived domains far more than for throwaway CRUD.

How I Work With Event Sourcing

I pick the aggregate as the stream unit. Each aggregate owns its event history, so the events tell the exact story of how that business object reached its state.

Events are designed as public contracts. I name each one in the domain's past tense, give it a version, and add upcasting for old events — the stream must stay readable years later.

Snapshots keep hot aggregates fast. I snapshot state periodically so replay is bounded, rebuilding from a snapshot plus the events since, rather than replaying an entire history every load.

Projections are explicit and idempotent. Read models derive from the stream and can be rebuilt on demand, which is both a feature and the simplest disaster recovery available.

Audit and temporal queries fall out nearly free. Once the facts exist, "what did we know when" and "why did this change" are simple queries, not archaeology projects.

The dual-write trap is avoided with an outbox. When an event must also reach a message broker, the event and the outbox row commit together, so the two never diverge.

Idempotent consumers prevent double-effect. Projections and subscribers must tolerate replay, so reprocessing an event never corrupts state.

I resist editing or deleting history. The stream is the source of truth; corrections are new events that supersede, keeping the audit trail intact.

I reach for event sourcing where it genuinely pays — money-moving, auditable, long-lived domains. For throwaway CRUD, the machinery is not worth it, and I say so plainly.

Key Capabilities

Append-only, immutable event log as the true source of state.
Projections and read models rebuilt at any point in time.
Full audit trail and temporal queries with no extra infrastructure.
Event contracts versioned and evolved like public APIs.
Replay and rebuild enable disaster recovery and analytics from the same store.