Event Sourcing
Event sourcing stores every state change as an immutable event log rather than storing current state directly.
What is event sourcing?
In traditional systems, you store the current state of an entity: {order_id: 123, status: "shipped", total: $49.99}. In event sourcing, you store the sequence of events that led to that state: [OrderCreated, ItemAdded, PaymentProcessed, OrderShipped]. Current state is derived by replaying events.
Core Concepts
Event
An immutable fact that something happened: OrderShipped { order_id: 123, timestamp: ..., carrier: "FedEx" }. Events are named in past tense - they represent things that have already occurred.
Event Log (Event Store)
A persistent, append-only log of all events, ordered by time. This log is the single source of truth. You never update or delete events.
Current State
Derived by replaying all events for a given entity from the beginning. This is the projection or aggregate state.
OrderCreated -> status: pending
PaymentProcessed -> status: paid
OrderShipped -> status: shipped
Advantages
Complete Audit Trail
The event log contains every state transition with full context. Perfect for compliance, debugging, and forensic analysis. "What was the state of order 123 at 2:00pm yesterday?" - replay events up to that timestamp.
Temporal Queries
Query state at any point in time by replaying up to that point. Impossible with traditional state storage without snapshot tables.
Event-Driven Integration
Other services can subscribe to the event stream and react asynchronously. Adding a new consumer (analytics, notifications) doesn't require changing the producer.
Debugging
Reproduce bugs by replaying the exact sequence of events that caused them.
Disadvantages
Query Complexity
Querying current state requires replaying events or maintaining pre-computed projections (read models). Simple queries like "get all active orders" require a separate read model updated by events.
Snapshots Required at Scale
For entities with thousands of events, replaying from scratch on every read is expensive. Solution: persist snapshots of state at regular intervals, then replay only events since the last snapshot.
Schema Evolution
Events are immutable - you can't change past events. When your event schema needs to change, you must version events and handle multiple versions in your replay logic.
Eventual Consistency
Read models (projections) are updated asynchronously from the event stream. There's a lag between write and readable state.
When to Use Event Sourcing
✅ Domain has complex business rules with many state transitions (e-commerce orders, financial transactions, reservations) ✅ Auditability is a hard requirement (finance, healthcare, legal) ✅ Need to support temporal queries ✅ Event-driven integration with multiple downstream consumers
❌ Simple CRUD with no meaningful history ❌ Team unfamiliar with the pattern - high accidental complexity ❌ Low write volume where complexity outweighs benefits
Event Sourcing + CQRS
Event sourcing is almost always paired with CQRS (Command Query Responsibility Segregation): writes go through the event log, reads come from pre-computed projections. This separates the write model (events) from the read model (optimised for queries).
Interview Angle
Event sourcing is a senior-level pattern. Bring it up for: "How would you implement an order management system?" or "How do you ensure an audit trail?" Then immediately address its costs: projection complexity, snapshots, schema evolution. Showing you know the tradeoffs is more impressive than just naming the pattern.