Skip to content

What is event-driven architecture?

Services exchanging facts that already happened through a broker, instead of calling each other directly and synchronously.

Event-driven architecture (EDA) is an architectural style where services communicate by publishing and subscribing to events, meaning notifications of something that already happened ("order created", "payment confirmed"), instead of calling each other directly and waiting for a synchronous response. A producer publishes the event to a broker without knowing who will consume it or when; every consumer receives it independently and reacts on its own terms. The conceptual difference that matters is between an event and a command: a command ("ship the order") imposes an action on a specific recipient and expects it to be carried out, an event states a fact and leaves whoever is listening free to ignore it, react to it, or queue it for later. This decouples producer and consumer in time (a consumer can be down and catch up later) and in space (the producer does not know the address of whoever is listening), unlike a direct REST call, which requires both sides active at the same instant.

See also: Apache Kafka · The open source distributed log for event streaming: topics split into partitions, read by independent consumer groups.

What each service gains, and what the system as a whole loses

Decoupling makes any single service simpler to write and evolve: a service does not need to know its consumers, adding a new one requires no change to the producer's code, and a failure in one consumer does not block the others. The price shifts to the system as a whole, and that is where most introductory documentation stops too early. Debugging becomes distributed: understanding why an order never reached its destination means reconstructing a chain of events across several services and several logs, not reading a stack trace. Message ordering is guaranteed only among events sharing the same partition key, never globally across the flow, and delivery is almost always "at least once", which means duplicates have to be handled downstream, the exact subject of idempotency and backfill. Consistency across services stops being immediate and becomes eventual, handled with compensations instead of an atomic rollback, exactly the territory the saga pattern covers. Eventual consistency is not only a technical problem: it is a decision someone has to sign off on, because a customer seeing their balance update a few seconds late is a business trade-off, not an implementation detail.

An enterprise example

A retailer with separate e-commerce, warehouse and billing systems replaced direct synchronous calls between the three (the order service called the warehouse, which called billing, in a chain that stalled entirely if one link was slow) with the publication of an "order confirmed" event: the warehouse and billing systems each consume it at their own pace, and a slowdown in billing no longer prevents the order from being confirmed to the customer. The cost of getting there was real: a duplicated event from a consumer restart generated two invoices for the same order, fixed only by introducing an idempotency key on the event, and reconciling the three systems required a dedicated tracing dashboard that had not been needed before.

Why it matters for decision makers

The question to ask before adopting it is not whether event-driven architecture is modern, but whether the system genuinely has multiple independent services that need to evolve at different paces. A back-office system with forty users and three stable integrations does not have this problem: introducing a broker adds a component that has to be operated, monitored and kept highly available, without solving anything that business actually had. The right call in that case is to stay on direct calls, and perhaps a well-scoped database-per-service split, not to add an event layer on principle. EDA pays off when the cost of decoupling is lower than the cost of continuing to evolve tightly coupled services, not as an architectural default.

  • Apache Kafka · The open source distributed log for event streaming: topics split into partitions, read by independent consumer groups.
  • Saga pattern · A sequence of local steps each paired with a compensating action, used to undo a distributed flow that fails partway through.
  • CQRS · Splitting the model that writes data from the one that reads it, instead of using a single model for both jobs.
  • Database-per-service · Each microservice owns its own datastore and no other service reads it directly, only through its exposed interfaces.
  • CAP theorem · During a network partition a distributed system must choose between consistency and availability, never both.

See it in the universe

If it touches your company's data, getting that data in order is the first thing I do.

SEE DATA FOUNDATIONS

Or write to me.