Back to the map

Module 11 · Architectural patterns · Lesson 5 of 9

Event-driven architecture

Services that react to things that happened instead of being told what to do. Events versus commands, notification versus state-carrying events, the broker as backbone, how it decouples teams and absorbs load.

CoreMust-knowSenior 13 minPro Updated Nov 2026

Why it matters

When checkout publishes "order placed" and lets inventory, billing, shipping, analytics and fraud each react in their own time, checkout becomes simpler and faster and new reactions can be added without touching it. That is the promise of event-driven architecture, and at scale it is how large systems stay changeable. The cost is that nobody can read the flow of a request from one place, consistency is eventual, and debugging crosses asynchronous hops. Designing an event-driven system well means getting the event design right, not just adding a broker.

The idea

In an event-driven architecture, components communicate by producing and consuming events: immutable facts that something happened, published to a broker and delivered to whoever subscribed. Producers do not know who consumes; consumers do not know who produced. The broker (Kafka, Pulsar, a cloud event bus) provides durability, ordering per key and fan-out, as the Communication patterns module covered.

Events, not commands

A command asks a specific recipient to do something and implies the sender knows what should happen next ("reserve stock"). An event states a fact in the past tense and leaves the consequences to consumers ("order placed"). Commands belong on queues to a known handler; events belong on topics for whoever cares. Confusing them produces events named like commands ("send email") that secretly couple the producer to one consumer.

Three kinds of event

KindPayloadConsumer behaviourTrade-off
Event notificationJust ids and type: 'order 9001 placed'Calls back to the producer's API for detailsSmall, always fresh; adds a synchronous dependency and load on the producer
Event-carried state transferThe full relevant state: order with items, customer, totalsKeeps a local copy; no callbackConsumers are autonomous and fast; data is duplicated and can be stale; schema matters
Event sourcingEvery state change as an event; the log is the source of truthRebuilds state by replayingFull history and audit; a different storage model (next lessons)

Most systems use state-carrying events for the fields consumers overwhelmingly need and ids for the rest, accepting that consumers hold eventually consistent copies.

Checkoutorder.placedevent brokerInventoryBillingShippingFraud (new)
Checkout publishes one fact. Each consumer reacts independently with its own backlog. Adding fraud detection touched nothing upstream.

What it buys

Decoupling in time and knowledge: producers stay simple and fast, consumers evolve independently, new consumers attach without coordination. Load levelling: bursts become consumer backlog. Resilience: a consumer outage delays its reaction instead of failing the producer. A natural audit trail and the ability to replay history into new consumers when the broker retains events.

What it costs

  1. 1

    Eventual consistency

    Consumers lag by milliseconds to minutes. The UI and the business must tolerate it (order confirmed, shipping label pending), and the consistency-model vocabulary applies.
  2. 2

    Hidden flows

    No file shows what happens after an order is placed. Documentation, event catalogues and tracing with correlation ids are mandatory, not optional.
  3. 3

    Schema coupling

    Every consumer depends on the event schema. Use a registry, additive-only evolution and versioned event types, as the Data formats lesson described.
  4. 4

    Delivery semantics

    At-least-once delivery means idempotent consumers; ordering holds only per key; the outbox pattern makes publishing reliable.
  5. 5

    Debugging

    A failed reaction surfaces far from its cause, later. Dead-letter queues, replay tooling and dashboards of consumer lag are the operational core.

Designing events

Name events as past-tense business facts from the producer's domain (OrderPlaced, PaymentCaptured), never as instructions. Include an event id, the aggregate id as key, a timestamp, a version and the state consumers need. Keep events about one aggregate. Discover them with the business through event storming: the facts people say happen are the events the system should publish. Treat the published events as a public API with the same care as REST contracts.

When not to

A request that needs an answer now (is this username free, what is the price) is a synchronous query, not an event. Workflows with strict sequencing and compensation are sagas with an orchestrator, which may use events as transport but keeps the flow explicit. Small systems with one team rarely need a broker; in-process events inside a modular monolith give the decoupling without the operations.

Event-driven architecture · Backplane