// Architecture Styles · 07
Event Sourcing
Store the events, not the state; replay them to get the state.
How it fits together
- Client uses / calls Account aggregate (1 command)
- Event store uses / calls Account aggregate (2 replay)
- Account aggregate creates Event store (3 append if v=2)
- Event store publishes / notifies Balance projection (4 new events)
- Balance projection creates Balance read model (5 update)
Spot it
- Auditors ask how a value got there
- You need the state as of a past date
- Updates overwrite facts the business needs
It costs
Full history and audit, but schema changes, replays and queries all get harder.
In code
public sealed class Account{ public decimal Balance { get; private set; } public int Version { get; private set; } public static Account Rebuild(IReadOnlyList<object> history) { var account = new Account { Version = history.Count }; foreach (var e in history) account.Apply(e); return account; } public MoneyWithdrawn Withdraw(decimal amount) { if (amount > Balance) throw new InvalidOperationException("Insufficient funds."); var withdrawn = new MoneyWithdrawn(amount); Apply(withdrawn); return withdrawn; } private void Apply(object e) => Balance += e switch { MoneyDeposited d => d.Amount, MoneyWithdrawn w => -w.Amount, _ => 0m, };}Go deeperThe full explanation and what to ask for · 1 min readExpandCollapse
Instead of updating rows, every change is appended as an immutable event, and current state is derived by replaying the stream. You get a complete audit trail, queries over past state, and new read models built from old history.
Do not use it everywhere. Events are kept forever, so versioning them is a permanent cost; long streams need snapshots; queries need projections; deleting personal data needs a plan. Apply it where history is the business, such as ledgers, and keep the rest as plain CRUD.
It almost always comes with CQRS, since the log is not queryable in useful shapes. It is not the same as event-driven architecture: keep internal stored events separate from the integration events you publish.
Ask for it
- event store
- append-only stream
- aggregate
- snapshot
- projection
- event versioning
Model the Account aggregate with event sourcing: append AccountOpened, MoneyDeposited and MoneyWithdrawn events to an append-only store with optimistic concurrency on the stream version, rebuild state by replay, and project a balance read model.