Lab 03: Event Sourcing & CQRS

Time: 50 minutes | Level: Architect | DB: PostgreSQL 15


🎯 Objective

Implement Event Sourcing with PostgreSQL as the event store. Build CQRS read/write models. Demonstrate event replay, projections, and snapshots. Compare with traditional CRUD.


📚 Background

Event Sourcing

Instead of storing current state, store a sequence of events (facts that happened):

Traditional CRUD:              Event Sourcing:
account: {balance: 700}   →   [Deposited(1000), Withdrew(200), Withdrew(100)]
                               Replay events → current state = 700

Benefits: Full audit trail, time travel (replay to any point), event-driven integration, easy "undo".

Drawbacks: More complex queries, eventual consistency for read side, event schema evolution.

CQRS (Command Query Responsibility Segregation)

Separate write model (commands → events) from read model (projections → optimized queries):


Step 1: Set Up PostgreSQL Event Store

📸 Verified Output:


Step 2: Write Events (Command Side)

📸 Verified Output:


Step 3: Event Replay — Reconstruct Current State

📸 Verified Output:


Step 4: Time Travel — Replay to Any Point

📸 Verified Output:

💡 Time travel query: In traditional CRUD, balance = 1250. With Event Sourcing, you can ask "what was balance on version 3?" — impossible with CRUD, trivial with events.


Step 5: Create Snapshot for Performance

📸 Verified Output:


Step 6: CQRS — Build Read Model Projection

📸 Verified Output:


Step 7: Compare Event Sourcing vs CRUD

📸 Verified Output:


Step 8: Capstone — Python Event Sourcing Framework

📸 Verified Output:


Summary

Concept
Key Takeaway

Event Sourcing

Events are source of truth; state = replay of events

Append-only log

Events never modified/deleted; use INSERT only

Event replay

Reconstruct any state by replaying event sequence

Time travel

Replay to any version = state at any point in time

Snapshot

Cache state at version N; replay only newer events

CQRS

Write model = commands/events; Read model = projections

Projection

Event handler that updates read-optimized view

Optimistic locking

expected_version prevents concurrent write conflicts

vs CRUD

CRUD: current state only; ES: full history, audit trail

💡 Use Event Sourcing when: audit trail is required (finance, healthcare, compliance), need time travel / state reconstruction, event-driven microservices, or undo/redo is a feature.

Last updated