Event-Driven Architecture & Event Sourcing
You'll learn to
- -Tell a command (do this) from an event (this happened), and say why events decouple services
- -Explain how publish/subscribe lets you add a new service without changing the publisher
- -Explain event sourcing: the append-only log as the source of truth, replay and snapshots
- -Name the costs: eventual consistency, event versioning, duplicates and harder debugging
A single queue feeding a single worker pool is the simplest asynchronous pattern: one job, one place it gets processed. Event-driven architecture generalizes it. Instead of saying do this one task, a service announces that something happened, and any number of independent services can react, without the original service knowing or caring who is listening. This chapter explains that idea, and a related one that takes it to its logical end: storing the events themselves as the source of truth.
An Analogy: A Town Crier and a Letter
A letter says please bake a cake: it is addressed to one person, it is an instruction, and the sender has to know who can bake. A town crier announces a baby was born: it is about something that already happened, it is addressed to nobody in particular, and the crier does not know or need to know who is listening. The baker may start a cake, the florist may send flowers, and next year someone new can start listening without the crier changing a word.
- -The letter is a command: an instruction to a known receiver, which may succeed or fail.
- -The announcement is an event: a fact about the past, named in the past tense (OrderPlaced), which cannot be refused.
- -The listeners are subscribers, each reacting in its own way.
- -A new listener joining without the crier changing is the decoupling that makes event-driven systems easy to extend.
How It Looks in a System
An Order service publishes one OrderPlaced event. Inventory reserves stock, Email sends a receipt, Analytics records a sale, and a new Fraud-check service can be added later by subscribing, with no change to the Order service at all.
One event, broadcast once: every interested service reacts independently, and new services can subscribe later without touching the order service at all.
Event Sourcing: Store the Events, Not Just the Result
A normal database stores the current state: this account has a balance of 120. Event sourcing stores every change instead, in an append-only log, and treats the current state as something you work out from it. Your bank statement is the everyday example: a list of deposits and withdrawals, from which the balance is derived. Here is the idea in a few lines, replaying four events:
Run it and read the last number on each line: 0, 100, 70, 120. Stopping after the third event shows the balance was 70 at that point, which is time travel for free. An append-only log of events has several useful properties:
- -A complete audit trail: you can see exactly what happened and in what order, which is valuable for money, medical and legal records.
- -Rebuildable views: a new report or search index can be built by replaying the whole history, even for questions nobody had thought of when the events were recorded.
- -Debugging: reproduce a bug by replaying the events that led to it.
- -Snapshots keep it fast: replaying millions of events for every read would be slow, so the system saves the state every so often (say every 1,000 events) and replays only the events after the latest snapshot.
What It Costs
- -Eventual consistency: subscribers react after the event is published, so other services see the change a moment later, not instantly.
- -Duplicates: delivery is usually at-least-once, so every subscriber must cope with seeing the same event twice.
- -Evolving events: an event written today must still be readable in five years, so changing its shape needs care.
- -Harder debugging: a single user action spreads across many services, so you need good tracing to follow it.
- -More machinery: for a simple application with one database, plain state is much easier. Use event sourcing where the history itself has value.
The Wiki card below goes further into event sourcing, including the read-model pattern that goes with it:
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.
In one line: a command asks for something, an event announces that something happened. Events decouple services, and event sourcing goes further by storing the events as the source of truth, with the current state derived by replaying them.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.
Level 5: Notification System is a message-queue-driven async system end to end.
Discussion0
Join the Discussion
Sign in to leave comments, reply to others, or like insights.
No comments yet. Be the first to start the thread!