Learning RabbitMQ
Imagine a busy kitchen. Orders come in on tickets. Some go to the grill, some to salads, some get held until a station is free. If a ticket is unreadable, it does not block the whole line — it goes to a side tray for someone to fix later.
That is roughly what RabbitMQ does for software — except the “orders” are messages, and the “kitchen stations” are background workers.
I am learning this on its own timeline. It is not bundled with Kafka or C++ — it just happens to be the one I am digging into most right now because of real work.
The simple idea
Something needs to happen later? Send a message. Something else picks it up and does the work.
The magic is in the routing — not every message goes to every worker — and in what happens when something fails.
flowchart LR
P[Sender] -->|message| X[Router]
X --> Q1[Queue A]
X --> Q2[Queue B]
Q1 --> W1[Worker 1]
Q2 --> W2[Worker 2]
Q1 -->|failed too many times| DL[Side tray: dead letters]
Router — decides which queue gets the message (like sorting tickets by station).
Queue — holds messages until a worker is ready (like the ticket rail).
Dead-letter tray — broken or rejected messages go here instead of clogging the line. In RabbitMQ this is called a dead-letter queue — same idea, less appetizing name.
Why RabbitMQ?
Lots of systems need “do this job next” behavior — send an email, run a build, process an upload. You do not always want the sender waiting around for the work to finish.
RabbitMQ shines when:
- Different types of work need different handlers
- You need to know a job was received and finished
- Failed jobs should retry or land somewhere inspectable — not vanish
It is a different shape of problem than “keep a history of everything that ever happened” (that is more Kafka territory).
How I am learning
Part work, part play.
At work I am touching pieces of a real pipeline migration — the kind where routing and failure handling actually matter, not just a tutorial hello-world.
At home I run Event Patterns — small send/receive demos with a dead-letter setup so I can break things safely.
Related write-up: Concourse → RabbitMQ migration — the work context in plain terms.
sequenceDiagram
participant App as App that sends work
participant R as RabbitMQ
participant Job as Background worker
App->>R: Here is a job
R->>Job: Deliver when ready
Job->>R: Got it, done
Note over R,Job: If Job keeps failing,<br/>message moves to dead-letter queue
Where this goes
Better gut feel for how work flows through a system — what gets routed where, what happens when a consumer crashes mid-job, and why “just add another queue” is never as simple as it sounds in a meeting.
That is the skill: designing reliable handoffs, not memorizing jargon.