Event-Driven Architecture — produce, publish, consume

Event-driven architecture on an interactive canvas: producers, the event bus, subscribers and the event store, and how decoupling lets new consumers join without touching producers.

Event-driven architecture decouples systems by making them communicate through events: producers publish what happened, the bus routes it to subscribers, and an event store keeps the history.

Event-Driven Architecture — produce, publish, consume

The interactive FlowJam canvas for this explanation — every lane, row and arrow above is a real QueryChart diagram you can open and edit.

How to read this visual

  • Read left to right: emit, publish, consume and retain.
  • The producers row never points at a consumer — every arrow crosses the bus, which is the decoupling made visible.
  • The bottom branch is the event store: the same events that are consumed in real time are also retained for replay and audit.

Producing and publishing

"Services produce domain events" is the producer's whole responsibility — recording that something happened. "Events are published to the bus" and "Bus routes events to subscribers" are the publish step: the bus accepts events and delivers them to whoever subscribed. The comment on the emit box makes the rule explicit — producers do not know who is listening, which is what makes the system extensible.

Consuming in real time

"Consumers process events asynchronously" is the right-hand path: subscribers act on each event — update a read model, send an email, trigger a workflow — on their own schedule. The async processing is why a slow consumer does not slow a producer, and why the visual keeps the two in separate bands.

Retaining the history

"Event store retains the full history" records every event in order, and "Events can be replayed for audit or recovery" is what the record is for — rebuilding a state, answering an audit question, or feeding a new consumer from the past. "New consumers join without touching producers" is the test of the architecture: because the history exists and the bus routes by subscription, adding a service changes nothing upstream.

Key relationships and takeaways

  • An event records what happened; it is not a command to anyone in particular.
  • The bus decouples producers from consumers — neither knows the other's identity or schedule.
  • The event store makes the history a system of record that can be replayed.
  • Consumers are asynchronous: a slow consumer never blocks a producer.
  • New consumers join by subscribing — the architecture's whole flexibility claim rests on that.

When to use this visual

  • Teaching the producer-bus-consumer split to a team moving from request/response to events.
  • Designing a new integration: the event store answers whether the history needs to be kept or consumed-and-forgotten.
  • Auditing an existing event-driven system for the classic failure — a consumer that is really a synchronous dependency.

How it works

  1. Rename the parties to your system

    Replace the producers, consumers and event names with your real services and the events they publish, adding the ones the generic diagram misses.

  2. Name the topics and their consumers

    Annotate each event on the bus with the topic name and who subscribes, so the decoupling is a documented map rather than an assertion.

  3. Add the failure branches

    Insert what happens when the bus is down, a consumer dies mid-event, or an event arrives twice — each with the idempotency or retry mechanism that handles it.

  4. Extend the event store

    Add the retention and replay rules your system actually uses — how long history is kept and which states are rebuilt from it — so the store band reflects your policy.

Frequently asked questions

What is event-driven architecture?

It is an architectural style in which components communicate by publishing and subscribing to events rather than calling each other directly. A service that creates or changes something publishes an event describing what happened; the bus routes it to every subscriber that cares; and an event store keeps the history. Because producers never name their consumers, the system can grow without touching what already exists.

What is the difference between a command and an event?

A command is an instruction aimed at a specific recipient — "process this order" — and it expects an outcome. An event is a record that something has already happened — "order placed" — and it names no recipient. The distinction matters because commands couple the sender to the receiver, while events leave the receiver free to change. The visual's producers only ever emit events, which is what keeps the bus loose.

What is the event store for?

The event store is the system's retained history: every event, in order, permanently. It serves three purposes — audit (what happened and when), recovery (rebuild a service's state by replaying its events), and extensibility (a new consumer can catch up by reading the past). The visual draws it as the bottom branch because it is a separate use of the same events that consumers process in real time.

What are the failure modes of event-driven architecture?

The classic ones are: events delivered more than once (so consumers must be idempotent), events processed out of order (so consumers must handle ordering), and the dead letter queue (events that fail repeatedly). The visual's asynchronous processing is what makes these manageable — a consumer can retry without blocking the producer — which is why the failure branches in the how-to steps are the practical half of the design.

Edit this visual in QueryChart (FlowJam)

Open this exact event-driven canvas as your own chart, rename the producers and consumers to your services, and map your events.

Edit this visual in QueryChart (FlowJam)

More in Visual explanations