Contact

What is Event-Driven Architecture?

Definition

Event-driven architecture is a software design approach in which services publish facts about state changes, such as “order created”, as events, and other services subscribe to those events and react on their own instead of being called directly. The publisher does not need to know who is listening, which loosens coupling between components but makes consistency and debugging harder.

Also known as: EDA, event, pub/sub, publish/subscribe, event-based architecture

Event-driven architecture: an order is published as an event and email, inventory and analytics services react to it independently via a bus

Commands tell, events announce

In a conventional design, the order service finishes its work and then tells billing to “create an invoice”, inventory to “reserve stock” and the mailer to “send a confirmation”. Those are commands: the sender knows the receiver and asks it to do something. Add a loyalty-points feature and the order service has to change as well.

In an event-driven design, the order service only announces an event: “order 1042 was created.” Events are named in the past tense, record an immutable fact and instruct nobody. Billing, inventory, email and loyalty each subscribe. Adding a new listener does not touch the publisher.

{
  "id": "7f3c2a90-1d4e-4b7a-9c61-0e5b8f2d4a11",
  "type": "order.created",
  "occurredAt": "2026-10-03T09:41:12Z",
  "data": { "orderId": 1042, "customerId": 88, "total": "1499.90", "currency": "EUR" }
}

The unique ID and the timestamp are there for a reason: the ID lets consumers discard duplicates, and the timestamp lets them interpret events in the right order.

Publish/subscribe

Events are usually distributed with publish/subscribe (pub/sub). The publisher sends to a topic, and every subscription receives its own copy. That differs from a classic message queue, where competing consumers share the work and each message goes to only one of them. RabbitMQ, Apache Kafka, the cloud providers' pub/sub services or, at small scale, Redis can carry the events. Across company boundaries the same idea appears as a webhook: an external service tells you over HTTP that something happened.

What you pay for loose coupling

  • Eventual consistency. The moment the order is saved, the invoice does not exist yet; it appears a few hundred milliseconds or one queue backlog later. User interfaces and business rules must allow for that gap.
  • Duplicates and ordering. Most infrastructure delivers events at least once and not always in order. Subscribers must be idempotent, and where order matters they should use version numbers or timestamps to ignore stale events.
  • Invisible flow. With direct calls you can follow the chain in the code. With events, “who reacts to this?” is only answerable at runtime, which makes distributed tracing close to essential.
  • Schema evolution. An event's shape is a contract. Removing a field can break a subscriber you did not know existed, so changes must stay backward compatible or be versioned.

The dual-write problem and the outbox pattern

The subtlest bug goes like this: a service writes the order to its database and then publishes the event to the broker. If the process dies between the two steps, the order exists but the event never goes out. Reverse the order and you may announce an order that was never saved. You cannot write atomically to two separate systems.

The usual fix is the transactional outbox. The event is inserted into an outbox table within the same database transaction as the order. A separate relay reads the table, publishes the events and marks them as sent. The order and its event now exist together or not at all, and a relay that crashes simply resumes where it left off.

When it is the wrong tool

Event-driven architecture shines when many teams evolve their services independently, when the number of reactions to a single fact keeps growing, and when work does not need an immediate answer. For an admin panel built by one team that mostly creates and lists records, a broker, eventual consistency and distributed debugging add more problems than they solve. A common middle ground is publishing and handling events inside a single application before splitting anything into microservices.

Related terms

← Back to the glossary