Skip to content

Messaging Patterns

Across this course you have met the building blocks. Here they are as named patterns you can reach for by name, each mapped to the exchange type that implements it.

One queue, many workers. Each message goes to exactly one worker, and the broker load-balances across them. This is the pattern for distributing tasks — resize this image, send this email, process this payment — where you scale throughput by adding workers.

One event, many independent subscribers, each with its own queue via a fanout exchange. Every subscriber gets its own copy. Use it to broadcast an event to systems that must each react — email, analytics, cache invalidation — without any of them knowing about the others.

Selective delivery. A direct or topic exchange sends a message only to the queues whose binding matches the routing key. Use it when different consumers care about different subsets of events — order.*.created here, payment.failed.# there.

Rebuilding synchronous call-and-wait on top of messaging, using correlation_id and reply_to. Occasionally useful, but usually a sign you actually wanted a real RPC/HTTP call — reach for it sparingly.

The architectural pattern above the others: services emit events (“OrderPlaced”) and other services react, with no central orchestrator telling them what to do. RabbitMQ is the nervous system carrying those events.

flowchart LR
  order["Order service"] -->|"OrderPlaced"| x["events exchange"]
  x --> q1["payment queue"] --> s1["Payment service"]
  x --> q2["inventory queue"] --> s2["Inventory service"]
  x --> q3["email queue"] --> s3["Notification service"]
Choreography — one event, many independent reactions

A note on sagas: when a business process spans several services (place order → charge → reserve stock → ship), choreography strings it together as a chain of events, and each step publishes the next. If a step fails, compensating events undo the earlier ones. RabbitMQ carries the events; the saga logic lives in your services.

You want to…PatternExchange type
Spread tasks across workersWork queuedirect / default
Broadcast an event to all reactorsPublish/subscribefanout
Deliver only to interested consumersRoutingdirect / topic
Get a reply to a requestRPCdirect (+ reply queue)
Let services react to events with no orchestratorChoreographytopic / fanout
In a work queue, how many workers process each individual message?
What distinguishes publish/subscribe from a work queue?
What is event-driven choreography?
Which pattern should make you pause and ask "did I actually want a normal RPC/HTTP call?"