Introduction
What event-driven architecture actually is
An event-driven architecture (EDA) turns a system into a pipeline of facts: a producer records that something happened — OrderPlaced, PhotoUploaded, PaymentSettled — and publishes it to a broker. Consumers read later, on their own schedule, and react. The producer does not know who the consumers are; consumers do not need the producer online when they run.
Four moving parts: an event (immutable record of a state change), a producer, a broker / topic, and a consumer. A topic groups related events; a consumer group cooperates so each event is processed once across the group (at-least-once in practice).
Why teams reach for it
- Decoupling in time and space — producer returns when the broker accepts; downstream can be slow or down.
- Fan-out — one event, many independent reactions without N sync calls from the producer.
- Independent scaling — scale consumers separately; broker absorbs bursts.
- Audit / replay — retained logs let new consumers rebuild state.
The price you pay
Writes and reads separate → eventual consistency. Failures go silent (lag instead of 500) → need lag dashboards and DLQs. Redelivery is normal → consumers must be idempotent. Dual-write (DB + broker) without an outbox loses or invents events.
Decision table: EDA vs sync RPC
| Need | Prefer | Why |
|---|---|---|
| Caller needs authoritative result now (charge, login) | Sync REST/gRPC | Clear success/fail path; strong UX |
| One action fans out to many reactions | EDA | Producer stays thin; consumers independent |
| Work can be seconds/minutes late | EDA | Absorb spikes; retry offline |
| Strong read-your-writes on next screen | Sync or sync+cache invalidation | EDA projections lag |
| Multi-step business with branching undos | Saga on top of events/commands | EDA alone is not a workflow engine |
Events are facts; commands are requests
The decision table above quietly leans on a distinction worth making explicit, because getting it wrong is how "event-driven" systems end up as RPC in disguise:
| Addressee | Can it be rejected? | Tense / meaning | |
|---|---|---|---|
Event (OrderPlaced) | None — producer does not know who consumes; 0..N consumers | No — it already happened; each consumer decides its own reaction | Past-tense, immutable fact |
Command (ChargeCard) | Exactly one known addressee | Yes — the receiver can fail or refuse; the sender owns the intent | Imperative: "do this" |
Query (GetOrderStatus) | One known addressee | N/A — reads state, changes nothing | Question |
The design tell: if the producer needs the result or names the recipient, it is a command — often better as a sync call or an orchestrator step — if it is announcing what already happened, it is an event. Publishing "events" like SendWelcomeEmail (imperative, one intended consumer, sender cares whether it worked) is command traffic wearing an event costume; it couples you to the consumer while giving up the sync call's clear failure path.
Queue vs pub-sub vs retained log
- Point-to-point queue — one worker gets each message; load-level identical workers; poor fan-out/replay.
- Ephemeral pub-sub — fan-out now; limited history.
- Retained log (Kafka-style) — many consumer groups, replay, audit; operational complexity higher.
Teaser with numbers: photo upload
User u_812 uploads a photo. Upload service writes object store + DB, then (via outbox) publishes PhotoUploaded. Four consumers: notifications, feed, moderation, analytics. Upload API p99 stays ~120 ms (broker accept); feed may update 200–2000 ms later. That lag is the product cost of decoupling — measure it as a consumer-lag SLI, not as an afterthought.
Pitfalls with detection
- Dual-write gap — DB committed, event never published. Detect: business rows without matching events; fix: transactional outbox/CDC.
- Poison messages — infinite crash loop. Detect: consumer restart rate; fix: DLQ after N fails.
- Schema breaks — required field added. Detect: consumer error spikes after deploy; fix: schema registry + compatibility rules.
- Ordering assumptions — global order is expensive; use partition keys for entity-local order only.
When NOT to use EDA
- Immediate consistent answer required.
- No real fan-out — one producer, one worker pool → simple queue or RPC.
- Team cannot operate brokers, lag, DLQ, schemas.
- Flow is a complex saga better modeled with an orchestrator than pure choreography.
Drill ladder
- Q: Why is "exactly-once" a myth for SMS send after Kafka consume? A: Broker EOS does not extend to external side effects; use at-least-once + idempotent send key.
- Q: Upload succeeds but feed empty for minutes — first metric? A: Feed consumer lag / DLQ depth / outbox relay lag.
- Q: Prefer queue or log for ride-sharing
RideRequestedwith matching + analytics + new consumer next month? A: Retained log for multi-group + replay.
Sources: Newman, Building Microservices; Richardson, Microservices Patterns; Kleppmann, DDIA.
🤖 Don't fully get this? Learn it with Claude
Stuck on Introduction? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Introduction** (System Design) and want to truly understand it. Explain Introduction from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Introduction** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Introduction** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Introduction** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.