Guide

When a customer places an order, a dozen things should happen. The card is charged, stock is reserved, a confirmation is emailed, the search index is updated, the sale is recorded for analytics, and the warehouse is told. One design is an OrderService.placeOrder method that calls twelve services in sequence. Every new feature adds a call, every downstream outage breaks checkout, and the orders team becomes a bottleneck.

The alternative is to announce one fact, "order 8812 was placed", and let every interested system react on its own. That is event-driven architecture. The term is overloaded. Martin Fowler counted at least four different patterns hiding under it, and teams that blur them build systems nobody can debug. This topic separates them: events from commands, notification from state transfer, change data capture, event sourcing, CQRS, and the pitfalls.

Reading order

StepConceptWhat it answers
1Events, commands and notificationsWhat is the difference between asking and announcing?
2Change data captureHow do you get reliable events out of an existing database?
3Event sourcingWhat if the events themselves are the source of truth?
4CQRS and read modelsHow do you query data that is stored as events?
5Pitfalls of event-driven systemsHow do these systems fail, and how do you prevent it?
6Worked example: an order system on an event logHow do the pieces fit together under load?

Coordinating a multi-step process is covered in orchestration versus choreography.

When to use it, and when not to

The senior judgment call is knowing when not to. A CRUD admin tool with three tables doesn't need event sourcing. Two services owned by one team rarely need choreography.

Introduce events when you can name the decoupling they buy. For example, "the email service can be down without affecting checkout." Then address ordering, duplicates and read consistency right away.

Mistakes that cause the most damage

  • Event soup. When anyone can subscribe to anything, nobody knows which services depend on which events. Changing a shape breaks unknown consumers.
  • Event sourcing as a default. It is a large commitment for every developer. Use it where history is the business.
  • Choreography for short flows. Two or three steps are easier to read as a direct orchestration.

Key takeaways

  • Commands ask one receiver to act. Events announce facts that any interested system can react to.
  • Thin events keep data in one place but cause callbacks. Fat events decouple availability at the cost of duplication.
  • Change data capture turns committed database changes into events, without dual writes.
  • Event sourcing stores events as the truth and derives state from them. CQRS builds read models for queries.
  • Design for ordering per key, duplicate delivery, schema governance and personal-data deletion from the first event.

In practice

At work, you will meet event-driven design mostly through:

  • CDC pipelines that feed search, caches and warehouses.
  • Domain events between services, including schema design, partition keys and versioning.
  • Workflow engines for long-running processes such as onboarding, payments and fulfilment.
  • Debugging lag and duplicates with consumer lag dashboards, dead-letter topics and idempotent handlers.

Further learning

Designing Data-Intensive Applications (Kleppmann) covers the log-based ideas behind this topic in depth.

Start with events, commands and notifications.