Architecture Expert
Event Sourcing — State as a History of Events¶
Event SourcingEventsCQRS 3 min read
Store state as a sequence of events. Event store, projections, snapshots, and implementation.
Principle¶
Instead of storing current state, you store a sequence of events. State is obtained by replaying all events.
# Traditional: Account { id: 1, balance: 150 }
# Event Sourcing:
AccountCreated { id: 1, balance: 0 }
MoneyDeposited { amount: 200 }
MoneyWithdrawn { amount: 50 }
# → Replay: 0 + 200 - 50 = 150
Event Store¶
class EventStore {
async append(aggregateId, events, expectedVersion) {
const current = await this.getVersion(aggregateId);
if (current !== expectedVersion) throw new Error('Concurrency conflict');
for (const event of events) {
await this.db.query(
'INSERT INTO events (aggregate_id, version, type, data) VALUES ($1, $2, $3, $4)',
[aggregateId, ++current, event.type, JSON.stringify(event.data)]
);
}
}
}
Projections¶
Events are not efficient for queries. Projections are read models updated with each new event. Snapshots store state after every N events.
Summary¶
Event Sourcing provides a complete audit trail and time travel. But it adds complexity. Use it where history is critical (finance, compliance).
Need Help with Implementation?¶
Our team has experience designing and implementing modern architectures. We’re happy to help.