Sign inGet started
Skills / Software-architecture

Event Sourcing

The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.

Event Sourcing is an architectural pattern where every change to application state is captured as an immutable event and persisted in an append-only event store. Instead of overwriting current state, the system stores the full sequence of events, allowing current state to be derived by replay. This enables complete audit trails, temporal queries (reconstruct state at any past moment), and powerful debugging and analytics — with clear trade-offs in complexity that this skill helps you navigate.

By Martin Fowler · Free
Specimen 01 · Live diagnosisEvent Sourcing
Input

“We're building a financial ledger for a fintech startup. Every account balance change needs a full audit trail, and regulators may ask us to…”

Diagnosis
I help you design Event Sourcing architectures grounded in Martin Fowler's canonical pattern — from evaluating fit to designing event schemas, aggregate reconstitution logic, projections, and snapshot strategies.
Full transcript ↓
Calibrated referenceagent-skills.ai
The gap

Store what happened, not just what is — rebuild any past state from your event log

Fowler's Event Sourcing pattern replaces the standard CRUD model — overwrite current state — with an append-only Event Store where every state change is recorded as an immutable Event object with a defined schema. Application state, encapsulated in Aggregates, is reconstructed at runtime by replaying events from the store. Snapshots provide a performance shortcut by capturing aggregate state at a point in time, avoiding full-history replay on large streams. Projections (Read Models) are derived views computed from the event stream, typically paired with CQRS (Command Query Responsibility Segregation) to separate write and read paths. The pattern enables temporal queries (reconstruct state at any past moment), complete audit trails, and event replay for debugging or analytics — but introduces meaningful complexity in schema evolution, eventual consistency management, and operational overhead.

The problem

Most systems store only current state — the last write wins, history is destroyed. When a financial discrepancy surfaces or a production bug needs reproducing, there is no record of what happened, in what order, or why. Engineers working on audit-heavy, compliance-regulated, or complex-domain systems find that CRUD-style state mutation erases exactly the information they most need.

The solution

Design an Event Sourcing architecture grounded in Fowler's canonical pattern: identify your domain events, structure your event store, design aggregate reconstitution logic, and plan projections — with explicit trade-off guidance so you adopt the complexity only when the benefits genuinely justify it.

You bring
  • A description of your domain: what entities change state, what business processes drive those changes
  • Your current or planned data storage approach and the pain points driving you toward Event Sourcing (audit, temporal queries, debugging, analytics)
  • Your tech stack and constraints (language, framework, persistence layer, team size)
  • Any existing domain model, event type sketches, or command/query structure you have so far
You get
  • A fit/no-fit assessment with specific trade-off analysis for your exact use case — including when simpler alternatives are better
  • A domain event inventory with schema sketches, metadata requirements, and a versioning strategy for schema evolution
  • Aggregate reconstitution logic design and snapshot timing recommendations for your event volume
  • Projection and Read Model designs for your query needs, including CQRS integration guidance
In action

Watch the methodology work.

Three specimens from a single real session: the same situation, unaided and calibrated, the full transcript, and the skill answering live in the channel where the work happens.

Fig.01The same situation, two ways
Specimens A · B
Specimen AVague
Unaided

“Your accounts table stores current_balance, status, and updated_at. A regulator requests the exact sequence of transactions on account #4821 between March 1 and March 15, 2024. Your DBA finds only the final balance and a single updated_at timestamp. An engineer spends two days piecing together history from fragmented application logs — and still cannot explain a $340 discrepancy that appeared sometime in that window.”

×Vague — nothing concrete to act on.
Specimen BCalibrated
With Event Sourcing

“Your event store contains every FundsDeposited, FundsWithdrawn, and AccountFrozen event for account #4821, each with amount, currency, processorReferenceId, initiatedBy, and a cryptographically sequenced timestamp. The regulator's request takes 15 minutes: filter events by date range, replay through the transaction-history projection. The $340 discrepancy is explained by a FundsWithdrawn event at 11:58 PM on March 12 initiated by system-process/fee-collection — fully auditable, unambiguous, and reproducible by any future replay.”

Specific, grounded, and ends with one clear next step.
Fig.02A real session, unedited
In-app · assistant
Event SourcingClaude
Event Sourcing
I help you design Event Sourcing architectures grounded in Martin Fowler's canonical pattern — from evaluating fit to designing event schemas, aggregate reconstitution logic, projections, and snapshot strategies. Before we dive into design, tell me about your system: what domain are you working in, and what's driving you to consider Event Sourcing? (Audit requirements, temporal queries, debugging complexity, or something else?)
We're building a financial ledger for a fintech startup. Every account balance change needs a full audit trail, and regulators may ask us to reconstruct account state at any past date. We're using PostgreSQL currently and just storing current balances in an accounts table.
This is a strong fit for Event Sourcing — three signals make your case compelling. First, you need complete audit trails by regulatory requirement, not just 'who changed it last' but the exact sequence of every change. Second, temporal queries are a hard requirement: 'reconstruct account state at date X' is precisely what Event Sourcing makes trivial and CRUD makes expensive. Third, financial ledgers are a canonical Event Sourcing domain because debits and credits ARE the domain events — a balance is a projection, not a ground truth.
One clarification before we design: are you starting greenfield, or migrating an existing accounts table? This significantly changes the approach.
Greenfield. We've sketched five event types: AccountOpened, FundsDeposited, FundsWithdrawn, AccountFrozen, AccountClosed.
Good starting inventory. Let me review against Fowler's 'events as first-class citizens' principle — events should be past-tense, business-meaningful, and represent irreversible facts:
AccountOpened, FundsDeposited, FundsWithdrawn, AccountClosed — Strong domain events. Past-tense, meaningful to the business, represent real state transitions.
⚠️ AccountFrozen — Valid, but consider: is unfreezing a separate event (AccountUnfrozen)? If accounts can be frozen and unfrozen repeatedly, you need an event pair rather than a toggled status disguised as an event. Otherwise you can't reconstruct the freeze/unfreeze history from the event log alone.
Now let's design the FundsDeposited schema as your representative example. Every event needs: event ID, aggregate ID (accountId), event type, sequence number, timestamp, and domain payload. For FundsDeposited — what fields does the business need in the payload? Amount, currency, processor reference, initiating user?
Yes — amount, currency (we're multi-currency), a reference ID from the payment processor, and who or what initiated it. Should we also store the resulting balance after the deposit in the event?
Do not store the resulting balance in the event. This is a documented anti-pattern — sometimes called 'snapshot-in-event' — and it violates a core Event Sourcing invariant.
In Fowler's model, the balance is a Projection: a derived value computed by replaying events through your Account Aggregate. If you embed the balance in the event payload, you introduce a redundant computed value that can drift out of sync with the event sequence. When you replay events — for debugging, temporal queries, or schema migration — which is authoritative: the replayed calculation or the stored figure? You've created ambiguity in your system of record.
Your FundsDeposited payload should be exactly: `{ amount, currency, processorReferenceId, initiatedBy }`. The balance is produced by your Account Aggregate: AccountOpened initializes state, each FundsDeposited and FundsWithdrawn updates the per-currency balance map, AccountFrozen/Unfrozen updates frozen status.
For multi-currency, your Aggregate state should track `{ [currency]: balance }` — a map updated by each deposit/withdrawal event. Want me to sketch the reconstitution logic, or move to snapshots first? With thousands of transactions per account you'll need a snapshot strategy.
Let's do snapshots — when should we introduce them, and how do they work alongside the event log?
Fowler's Snapshot pattern answers this exactly. The core rule: introduce snapshots when aggregate reconstitution latency becomes a measured problem in production — not speculatively before launch.
For a financial ledger, a practical strategy is event-count-based snapshotting: after every N events on an aggregate (e.g., every 500 transactions), persist a snapshot of the full Aggregate state — your multi-currency balance map, frozen status, version number. On the next load, start replay from the most recent snapshot, then apply only events after its sequence number.
The non-negotiable constraint: snapshots are read-optimization only, never replacements. Never delete events to save storage — your event log is your immutable system of record and your audit trail. Snapshots are a derived cache layer on top of it.
This means your event store queries become: 'Give me the latest snapshot for accountId X, then all events with sequence > snapshot.version.' Your Aggregate reconstitution starts from snapshot state rather than zero.
Next step: shall we design your Projections? For CQRS read models you'll need at minimum a current-balances projection (per account, per currency, for fast API responses) and a transaction-history projection (for audit and customer-facing history). Temporal queries — 'state at date X' — are answered by replaying events up to that timestamp, which your immutable event log makes straightforward.
Reply to Event Sourcing
What the skill is doing
01Fit Assessment
02Domain Event Identification
03Event Schema & Versioning Design
Fig.03The same skill, in the channel you already use
WhatsApp · live
9:41
ESEvent Sourcingtyping…
Messages are end-to-end encrypted. No one outside of this chat can read them.
Today
We're building a financial ledger for a fintech startup. Every account balance change needs a full audit trail, and regulators may ask us to reconstru…9:14✓✓
Before we dive into design, tell me about your system: what domain are you working in, and what's driving you to consider Event So…9:14
(Audit requirements, temporal queries, debugging complexity, or something else?)9:15
Message

The same skill, where the work happens.

No new app to learn. The methodology runs over the WhatsApp Business API, so the answer lands as a reply in the thread you’re already in — same rigour, zero context-switch.

Reads the situation, names the pattern, returns one concrete next move.
Delivered in seconds, inside a conversation that already exists.
Specimen · WhatsApp Business API · live
Capabilities

What it does, specifically.

Each capability is a distinct move drawn straight from the source methodology — not a generic assistant guessing.

CapabilityC-01

Fit Assessment

Evaluates whether Event Sourcing is appropriate for your specific use case based on your domain's audit requirements, temporal query needs, team maturity, and operational constraints. Produces an explicit recommendation including cases where simpler alternatives (audit tables, change data capture) are more appropriate.

Based on Fowler's documented guidance that Event Sourcing is warranted primarily for audit trails, temporal queries, and complex domain behavior — and his acknowledgment that the pattern's complexity is unjustified for many straightforward CRUD systems.
CapabilityC-02

Domain Event Identification

Guides you through identifying, naming, and scoping the domain events that should be captured in your system. Distinguishes business-meaningful state changes from low-level technical noise, and reviews event naming for clarity and correctness.

Applies Fowler's principle that events represent 'changes to application state' as first-class objects, ensuring events are past-tense, business-meaningful, and represent irreversible facts rather than commands or technical mutations.
CapabilityC-03

Event Schema & Versioning Design

Designs the structure of each event type: required domain payload fields, metadata (event ID, aggregate ID, sequence number, timestamp, causation and correlation IDs), and a versioning strategy for handling schema evolution as your domain model changes over time.

Addresses Fowler's identified challenge of schema evolution — one of the most operationally critical and underspecified aspects of Event Sourcing — including upcasting strategies and backward-compatibility patterns.
CapabilityC-04

Aggregate Reconstitution Design

Designs the logic by which your Aggregates are rebuilt from event replay: the apply/fold pattern, how each event type mutates aggregate state, handling of corrupted or out-of-order events, and integration with your domain model structure.

Directly implements Fowler's core Event Sourcing mechanism — 'application state is rebuilt by replaying events from the log' — with Aggregates as the unit of reconstitution and events as the authoritative state transition record.
CapabilityC-05

Projection & Read Model Design

Designs Projections (Read Models) derived from your event stream for query purposes: which events each projection consumes, the data shape it produces, rebuild strategies, and how to integrate CQRS to cleanly separate command and query responsibilities.

Based on Fowler's pattern of Projections as derived views computed from the event stream, and his documentation of CQRS as a natural architectural complement that cleanly separates the append-only write path from the query-optimized read path.
CapabilityC-06

Snapshot Strategy Planning

Determines when and how to introduce Snapshots to avoid full-history replays on large aggregate streams, including snapshot frequency heuristics, storage approach, and how snapshots interact with event replay logic without compromising event log immutability.

Implements Fowler's Snapshot pattern — periodic state captures allowing aggregate reconstitution to start from a recent snapshot rather than event zero — as a read-performance optimization that must never replace or delete the underlying event log.
CapabilityC-07

Anti-Pattern Review

Reviews your current or planned Event Sourcing design against documented failure modes: storing derived state in events, treating events as CRUD synonyms, anemic event stores, ignoring idempotency requirements, conflating domain events with integration events, and premature snapshotting.

Synthesizes pitfalls grounded in Fowler's conceptual boundaries for Event Sourcing — particularly the 'event as first-class citizen' principle — and common misapplications that arise when teams apply the pattern without fully internalizing its invariants.
Tested

Graded before it shipped.

Every skill is scored against independent scenarios for methodology fidelity before it goes live — not vibes, a rubric.

What it produces
OutputD-01

Event Inventory & Schema Sketches

A structured catalog of your domain events with proposed field names, types, metadata requirements (IDs, timestamps, sequence), and a versioning approach — the foundational design document for your event store.

OutputD-02

Aggregate Reconstitution Blueprint

A design document showing how each Aggregate is rebuilt from event replay: the apply/fold logic per event type, snapshot integration points, and edge-case handling for your specific domain.

OutputD-03

Projection Design Map

A mapping of query needs to Projection designs: which events each projection consumes, the data shape it produces, rebuild strategy, and how it integrates with your CQRS read side.

OutputD-04

Fit & Trade-off Decision Summary

A documented assessment of whether Event Sourcing is appropriate for your use case — with specific trade-offs called out, alternatives considered, and a recommendation on scope (full ES, hybrid, or alternative pattern).

The source

Grounded in the original work.

Every answer traces back to a real source and the practitioner who wrote it — not a secondhand summary. Here is the source of record.

Source authorA-01

Martin Fowler

Martin Fowler is Chief Scientist at ThoughtWorks and one of the most influential voices in software architecture. He is the author of foundational texts including 'Patterns of Enterprise Application Architecture', 'Refactoring: Improving the Design of Existing Code', and 'UML Distilled'. His website martinfowler.com is a canonical reference for enterprise software patterns, and he is a signatory of the original Agile Manifesto.

Status · Inspired by Martin Fowler’s work — not yet claimed. Are you Martin Fowler?
Primary sourceS-01

Patterns of Enterprise Application Architecture

by Martin Fowler

Chief Scientist at ThoughtWorks; author of 'Patterns of Enterprise Application Architecture' and 'Refactoring'; signatory of the Agile Manifesto; martinfowler.com is a canonical reference for software architecture patterns.

Read the original ↗
Citationmartinfowler.com
In the build queue

Be first to run it.

Event Sourcing is being built right now. Leave your email and we’ll tell you the moment it goes live.

Notify meEmail
At launchI'm considering Event Sourcing for [describe your system — e.g., 'a financial ledger' / 'an inventory system' / 'an order management platform']. My main driver is [audit requirements / temporal queries / debugging / event-driven integrations]. Can you help me assess fit and start designing the event schema?