Mermaid code
flowchart LR
subgraph Producers
Checkout[Checkout service]
Billing[Billing service]
end
subgraph Bus["Event bus"]
T1[orders topic]
T2[payments topic]
DLQ[Dead-letter queue]
end
subgraph Consumers
Ship[Shipping service]
Email[Email service]
Ledger[Ledger service]
end
Checkout -- OrderPlaced --> T1
Billing -- PaymentCaptured --> T2
T1 --> Ship
T1 --> Email
T2 --> Ledger
T2 --> Email
Ship -. failed after 5 retries .-> DLQ Paste this into any tool that renders Mermaid, or into the editor to change the theme and export PNG or SVG. Syntax reference: Flowchart guide.
What this diagram shows
The Checkout service publishes OrderPlaced to the orders topic; Billing publishes PaymentCaptured to the payments topic. The Email service subscribes to both, which is the kind of fan-in that is easy to miss in code. The dotted edge from Shipping to the Dead-letter queue shows what happens after five failed processing attempts, and the edge label states the retry policy so nobody has to look it up.
Three subgraphs give the diagram its structure. Because every edge crosses a subgraph boundary, the reader can see at once that no service depends on another service directly.
How to adapt it
- Name topics after the aggregate they describe (
orders,payments,inventory) and events in past tense (OrderPlaced), the convention most teams settle on. - Add one dotted edge per consumer to the
DLQonly if each has its own retry policy; otherwise one representative edge keeps the diagram readable. - Use
flowchart TDand put the bus in the middle row if you have more than five consumers. - Add a
Replaynode with an arrow from theDLQback to the topic to document how operators recover poisoned messages.
FAQ
How do I show that a consumer is idempotent?
Add a short note in the node label, for example Ledger service<br/>idempotent by event id. Mermaid flowcharts have no annotation syntax, so the label is the place for it.
Should the bus be a subgraph or a single node?
A subgraph when you want to show topics individually, which is almost always more useful. A single hexagon node is enough for a high-level overview where topics do not matter yet.