Event Sourcing flips traditional database design on its head. Instead of storing current state, you store the events that led to that state. It’s not for every project, but when it fits, it’s powerful.
The Concept
In a typical system, you update records in place. An order goes from “pending” to “shipped” by updating a status column. The previous state is lost.
With Event Sourcing, you store events: OrderPlaced, PaymentReceived, OrderShipped. Current state is derived by replaying events.
// Traditional: current state
UPDATE Orders SET Status = 'Shipped' WHERE Id = 123;
// Event Sourcing: append event
INSERT INTO Events (StreamId, EventType, Data, Timestamp)
VALUES ('order-123', 'OrderShipped', '{"carrier": "DHL"}', NOW());
Events Are Immutable Facts
public abstract class DomainEvent
{
public Guid EventId { get; } = Guid.NewGuid();
public DateTime OccurredAt { get; } = DateTime.UtcNow;
}
public class OrderPlaced : DomainEvent
{
public Guid OrderId { get; }
public Guid CustomerId { get; }
public List<OrderLine> Lines { get; }
}
public class OrderShipped : DomainEvent
{
public Guid OrderId { get; }
public string TrackingNumber { get; }
public string Carrier { get; }
}
Rebuilding State
public class Order
{
public Guid Id { get; private set; }
public OrderStatus Status { get; private set; }
// Rebuild from events
public void Apply(OrderPlaced e)
{
Id = e.OrderId;
Status = OrderStatus.Placed;
}
public void Apply(OrderShipped e)
{
Status = OrderStatus.Shipped;
}
}
// Load aggregate
var events = await eventStore.GetEvents("order-123");
var order = new Order();
foreach (var e in events)
{
order.Apply((dynamic)e);
}
Benefits
- Complete audit trail: Every change is recorded
- Temporal queries: “What was the state last Tuesday?”
- Event replay: Rebuild projections, fix bugs, run simulations
- Debugging: Understand exactly how state evolved
Challenges
- Complexity: Significant learning curve
- Event versioning: Schema changes are tricky
- Eventual consistency: Read models may lag
- Storage growth: Events accumulate forever
When to Use It
Event Sourcing fits when you need audit trails, temporal queries, or complex domain models. It’s overkill for simple CRUD. Consider it for financial systems, booking systems, or anywhere history matters.
References
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.