💾 Publish Your Image to RabbitMQ
Ship Your Renders to a Message Broker (and why you'd bother)
- images
- STRING
This node takes the image sitting in your workflow and drops it onto a RabbitMQ exchange as a base64-encoded PNG. If that sentence already makes sense to you, you know who you are and you can stop reading at the code blocks. For everyone else: this is the "tell another service a render is done" node, the ComfyUI half of an event-driven pipeline.
Why would you want that? Most people are perfectly happy with ComfyUI saving images to disk. But if you're building the kind of setup where a separate app needs to know the moment a generation finishes - a web frontend, a Discord bot, a processing service that crops or archives renders - polling the output folder is gross, and RabbitMQ gives you a clean publish/subscribe handoff instead. You publish, your consumer subscribes, nobody polls anything. It's the same pattern that "I made a queue system for stable diffusion" reddit post was reaching for years back, just with RabbitMQ as the glue.
How it works
The pack is one node and a thin pika client. When the node fires it converts each frame of the incoming images tensor to a PNG, base64-encodes it, and publishes a single JSON message like:
{
"images": [{"batch_number": 0, "base64_data": "..."}],
"prompt_id": "..."
}
to the exchange, then closes the connection. The prompt_id comes from ComfyUI's last_prompt_id, so your consumer can tie a message back to the exact run that produced it - genuinely handy for correlating renders with requests. There are no models to download and no heavy dependencies; the whole thing is a few hundred lines.
The inputs that matter
Eleven inputs, but you'll touch maybe four. RabbitMQ's defaults are sane, so it starts with host: localhost, port: 5672, username/password: guest/guest. You actually set:
images- your IMAGE tensor goes in here. Yes, the one you'd normally send to Save Image.host/port- where your broker lives. Change these if RabbitMQ isn't on the same machine.exchange/routing_key- the exchange name and the key your consumer binds to.comfy/imageby default.exchange_type-direct,fanout, ortopic. Fanout blasts to every queue bound to the exchange; direct and topic are for routing. Leave it alone until you understand which you need.
durable, auto_delete, and internal are exchange-declaration flags; the defaults (durable: true, the rest false) are right for most setups. The declared STRING output is effectively decorative - this is a terminal node. You wire images in; nothing meaningful comes out to consume downstream.
Install
Via ComfyUI Manager, search "ComfyUI-RabbitMQ-Publisher" and hit install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/Poseidon-fan/ComfyUI-RabbitMQ-Publisher
then restart ComfyUI. The requirements.txt pins pika==1.3.2, numpy==2.1.3, and pillow==11.0.0 - pika is tiny, but the exact numpy pin has been known to nag in environments where another pack wants a different version.
Where people get burned
The node connects to RabbitMQ; it does not run RabbitMQ. If you don't have a broker up, this node just errors. You need RabbitMQ installed and listening before this pack is anything but a paperweight.
Second trap, and it's a classic: RabbitMQ's default guest user is restricted to localhost connections. Point host at a remote broker with guest/guest and it'll fail with ACCESS_REFUSED. Create a real user with permissions for your exchange:
rabbitmqctl add_user comfy comfysecret
rabbitmqctl set_permissions -p / comfy ".*" ".*" ".*"
Third: payloads. Every batch frame becomes a base64 PNG inside one message, so a big batch at high resolution turns into tens of megabytes of JSON. RabbitMQ's default message-size cap is 128 MiB; you'll hit it before you expect to if you're publishing 8×1K renders at once. Keep batches small, or have your consumer ack-and-fetch instead of trying to slurp the whole blob.
Also worth knowing before you build anything that faces the internet: nothing here is authenticated, and ComfyUI's own API isn't either - the ecosystem has had loud PSA threads about exposing an unsecured instance. This node is for an internal pipeline, not a public endpoint.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| exchange | STRING | comfy | — |
| routing_key | STRING | image | — |
| host | STRING | localhost | — |
| port | INT | 5672 | — |
| username | STRING | guest | — |
| password | STRING | guest | — |
| exchange_type | COMBO | direct | 3 options: fanout, direct, topic |
| durable | BOOLEAN | true | — |
| auto_delete | BOOLEAN | false | — |
| internal | BOOLEAN | false | — |
| images | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |