Event-Driven Architecture & Event Sourcing
You'll learn to
- -Explain the append-only log as a source of truth
A single queue feeding a single worker pool is the simplest async pattern: one job, one place it gets processed. Event-driven architecture generalizes this: instead of "do this one task," a service broadcasts "this happened," and any number of independent services can react to it without the original service knowing or caring who's listening.
One event, broadcast once: every interested service reacts independently, and new services can subscribe later without touching the order service at all.
Instead of storing current state, store a full append-only log of every event that led to the current state. The log IS the database.
A bank doesn't store just your current balance ($1,247.50). It stores every transaction ever: +$2,000 salary, -$800 rent, -$50 grocery, +$100 transfer. Your current balance is DERIVED by replaying all events. If there's a dispute, every step is auditable. You can see exactly how the balance reached $1,247.50.
In traditional CRUD systems, you UPDATE rows. When the row changes, you lose the history. Event sourcing flips this: you APPEND events. The current state is derived by replaying events from the beginning (or from a snapshot).
Event Store: An append-only log (never update, never delete). Each event has: event_type, aggregate_id, payload (what changed), timestamp, and sequence_number. Kafka is an excellent event store. EventStoreDB is purpose-built for this.
Projections / Read Models: The log is the source of truth, but querying it directly (replaying all events every time) would be slow. Instead, you build eventual-consistency read models (also called projections or views) by processing the event stream. Each read model is optimized for a specific query pattern.
Benefits: Complete audit trail. Time travel - replay events to see state at any point in history. Debugging - you know EXACTLY what sequence of events caused a bug. Enabler of CQRS and event-driven microservices.
Challenges: Events are immutable, but requirements change. If an event schema changes (new field), you need an evolve strategy. Replaying millions of events to rebuild state is slow - use snapshots (periodically save state, only replay from snapshot). High learning curve.
- -Best suited for: financial systems (full audit), collaborative systems (conflict resolution), regulatory compliance domains.
- -Snapshots prevent cold-start performance issues (never replay full history).
- -Usually paired with CQRS (Command Query Responsibility Segregation): write side uses events, read side uses optimized projections.
- -Kafka is not a database, but its log retention + consumer groups make it work for event sourcing.
- -Strong coupling between events and aggregate - versioning events carefully is critical.
What does event-driven architecture buy you that a service directly calling three other services' APIs doesn't?
"It's more modern and uses queues instead of direct calls."
"Decoupling in both directions. The order service doesn't need to know inventory, email, and analytics exist, let alone call all three and handle each one's failures; it just publishes one event. And adding a fourth consumer later (say, fraud detection) requires zero changes to the order service: it just subscribes to the same event. Direct service-to-service calls mean every new consumer is a code change in the caller; event-driven means it isn't."
Why offload slow work (video encoding, PDF generation) to a background worker instead of handling it inline in the web server?
Level 5: Notification System is a message-queue-driven async system end to end.