Event-Driven Architecture Diagram: How to Draw Kafka Producers, Topics and Consumers

In an event-driven system the call graph disappears into topics. A notation for producers, topics, consumer groups and failure paths that keeps the flow readable.

10/22/2026

Event-Driven Architecture Diagram: How to Draw Kafka Producers, Topics and Consumers

In a request and response system, the arrows on the diagram are the call graph. In an event-driven system they are not. A producer writes an event to a topic and does not know who reads it. Draw that naively, every service connected to one big Kafka box, and the diagram hides everything you need: which events exist, who reacts to them, in what order, and what happens when a consumer fails.

This guide gives you a notation for event-driven architecture diagrams that keeps the flow readable, walks through an order processing example on Kafka, and covers the details people forget to draw: keys, consumer groups, the outbox and the dead-letter path.

What the diagram has to show

An event-driven diagram should answer these questions without a separate document:

  • Which events exist? Named in the past tense, such as OrderPlaced or PaymentFailed.
  • Who produces each one? Exactly one owner per event type is the healthy default.
  • Who consumes it, and as which consumer group? In Kafka every consumer group gets every event, so each group is a separate reader.
  • What decides ordering? Kafka keeps order only within a partition, and the key picks the partition.
  • What happens on failure? Retries, dead-letter topics, and who replays.

A notation that works

Element How to draw it
Producer A service node with a dashed edge to the topic, labeled with the event type
Topic Its own node, named as in the cluster (orders.v1), with the key in the label
Consumer group A dashed edge from the topic to the consumer, labeled with the group id
Event vs command Events in the past tense (OrderPlaced), commands in the imperative (ReserveStock)
Dead-letter topic A separate topic node, fed by the consumer that gave up
Connector A node between a topic and an external store, such as a warehouse sink
Broker cluster A frame around the topics; brokers and partitions go on the ops diagram

Use solid edges only for synchronous calls, such as an HTTP request to a payment provider. Then a reader can tell at a glance which parts of a flow happen in the same request and which happen later.

The example: order events on Kafka

An online store processes orders with events:

  1. The orders service writes the order and an outbox row in the same database transaction.
  2. An outbox relay (Debezium on Kafka Connect) reads the outbox through the database log and publishes OrderPlaced to orders.v1, keyed by order_id.
  3. Three consumer groups read orders.v1: payments charges the card, inventory reserves stock, and a warehouse sink loads every event into the data warehouse.
  4. Payments publishes PaymentSucceeded or PaymentFailed to payments.v1, also keyed by order_id, and the orders service consumes it to update the order status.
  5. When inventory cannot process a message after three attempts, it writes the message to inventory.dlq and moves on.

Here is the whole flow on one canvas:

Event-driven diagram: orders writes orders and outbox rows to its database, and a Debezium relay publishes them to orders.v1. Payments, inventory and a warehouse sink consume it; payments replies on payments.v1, read by orders.

11 components · 10 connections

Open in Archboard
Diagram contents
  • Orders
  • Orders DB (orders + outbox)
  • Outbox relay
  • Kafka cluster
  • payments.v1 · key order_id
  • orders.v1 · key order_id
  • inventory.dlq
  • Payments
  • Warehouse sink
  • Inventory
  • Data warehouse
  • order + outbox row, one transaction
  • reads WAL
  • OrderPlaced
  • group: payments
  • group: warehouse-sink
  • group: inventory
  • PaymentSucceeded/Failed
  • group: orders
  • load
  • after 3 failed attempts
Order events on Kafka: the outbox relay publishes OrderPlaced, three consumer groups react, payments answers on its own topic, and failed inventory messages land in a dead-letter topic.

Notice what the diagram makes obvious: nobody calls payments, adding a fourth consumer group changes nothing upstream, and events for one order stay in order within each topic because both are keyed by order_id (Kafka gives no ordering across topics).

Five rules for event-driven diagrams

1. Topics are nodes, not arrows

An arrow from orders to payments labeled "Kafka" suggests a call that does not exist. Draw the topic as a node between them. It is a real thing with a name, an owner, a retention period and a schema.

2. Arrows follow the data

Draw producer to topic to consumer, in the direction the data moves. Kafka consumers pull, but a diagram that points arrows from consumers to topics reads backwards to almost everyone. If pull semantics matter for the discussion, add a note.

3. Label events and consumer groups

Put the event type on the producer edge and the consumer group on each consumer edge. When someone asks "who else reads OrderPlaced?", the answer is the list of labeled edges leaving the topic.

4. Show the key when ordering matters

Kafka guarantees order within a partition, and events with the same key go to the same partition. If your consumers rely on seeing OrderPlaced before OrderCancelled, write the key on the topic: orders.v1 · key order_id. A topic without a key in the label invites the question.

5. Draw the unhappy path

Kafka consumer groups have no built-in dead-letter queue: your consumer code or framework decides how many times to retry and where to put a message it cannot process (Kafka Connect sink connectors do have a dead-letter topic setting). Draw that decision. A dead-letter topic with an edge from the consumer, and a note on who watches it and how messages get replayed, saves an incident.

Draw the outbox, not the shortcut

If a service writes to its database and then publishes to Kafka in two separate steps, a crash between them loses an event or publishes one for a change that never committed. The outbox pattern avoids that dual write: the service writes the event to an outbox table in the same transaction, and a relay publishes it.

On the diagram, draw the real path: service to database to relay to topic. A direct arrow from the service to the topic would describe a different, less reliable system, and people will make decisions based on it.

Choreography or orchestration

The example uses choreography: services react to each other's events, and no one is in charge of the whole flow. If you use an orchestrator instead, a workflow engine that sends commands such as ReserveStock and waits for replies, draw the orchestrator as a service in the middle and label its edges as commands. Either way, number the steps of the main flow on the edges so readers can follow the saga in order.

Keep the cluster out of the logical view

Brokers, partitions, replication factors and controller nodes matter for capacity and operations, not for understanding the flow. Put them on a separate ops diagram. On the logical view, a frame labeled "Kafka cluster" around the topics is enough.

Build it in Archboard

  1. Sign in with Google or GitHub and create a diagram.
  2. Add the services as Container nodes from the C4 Model pack, and the orders database from the Data pack (Postgres).
  3. Add a Core Frame labeled Kafka cluster and put Topic nodes from the Data pack inside it.
  4. Add the outbox relay and the warehouse sink as containers with Kafka Connect in the technology field, and a Data Warehouse node from the Data pack.
  5. Connect ports, set event edges to a dashed line, and label them with event types and consumer groups.
  6. Open it in presentation mode for the review, share the live link, or export SVG and PNG.

The example uses 11 diagram nodes, within the Free plan's 15. For another streaming layout, see /examples/streaming-data-platform, and for the synchronous side of a similar store, the microservices architecture diagram guide.

FAQ

Should I draw partitions? Not on the logical view. Write the partition count in the topic label if it matters, and draw partitions and brokers on an ops diagram.

How is a queue different from a topic on the diagram? In a queue, each message goes to one consumer; in a Kafka topic, each consumer group gets every message. Use a Queue node for queues such as SQS or RabbitMQ, and say which semantics you rely on.

Where do event schemas go? In a note or the topic label, with a link to the schema registry or the repository that owns the schema. The diagram should show that a contract exists and where it lives.

How do I show replay? Write the retention on the topic (for example retention 7d) and add a note on how a consumer group resets its offsets. Replay is a design feature; make it visible.

Do I need one diagram per event? No. One diagram per business flow works well. List the events on the edges, and keep an event catalog for the full list.

Start free — one seat, no credit card.

Related posts

← Back to blog

Open a canvas in a minute

Sign in with Google or GitHub. Free for a single seat. Upgrade when the team joins.