Engineering notes — 2026-11-03
BullMQ vs RabbitMQ: What Two Production Queue Layers Taught Me
BullMQ vs RabbitMQ is the wrong starting question: the workload decides the queue, not the other way around. This guide walks the real trade-offs from running a Redis-backed BullMQ layer that schedules thousands of concurrent AI jobs — and the cases where I would pick RabbitMQ anyway.
Queue debates happen at architecture-review tables where nobody has the numbers yet. I have been on both sides: BullMQ carries the entire job layer of RealStream, an AI media platform scheduling thousands of concurrent inference jobs, and I have integrated RabbitMQ in polyglot environments. They are not competitors so much as different tools shaped by different problems. Here is how I would choose today.
What BullMQ actually buys a Node.js team
BullMQ is not a generic message broker; it is a job platform for Node.js built on Redis. That focus is its whole value:
- Job semantics out of the box: delayed jobs, priorities, rate limiting, retries with capped backoff, stalled-job detection, repeatable/cron jobs.
- An idiomatic TypeScript API and a job event stream that doubles as user-facing status (in RealStream, stage transitions reach users over WebSockets from the same events the ops view reads).
- One fewer piece of infrastructure: if your stack already runs Redis, the queue layer rides on it. Production throughput at tens of thousands of jobs per minute on a single Redis node is documented and well understood.
Where RabbitMQ earns its place
RabbitMQ is an AMQP broker designed for message routing between systems, not primarily for job convenience inside one stack. Three signs it is the right tool:
- Polyglot services: producers and consumers in different languages and runtimes, all speaking one protocol.
- Complex routing: topic/headers exchanges distributing each message to different consumers by content — routing BullMQ does not aim to replicate.
- Delivery guarantees between services as a product requirement, with acknowledgements and dead-letter flows defined at the protocol level rather than in application code.
The comparison that matters: failure modes
Both systems fail, but differently, and the difference is the real decision driver. With BullMQ, reliability concentrates on one dependency: Redis. That is a single point carrying your job layer, so persistence strategy, replication or a managed instance, and monitoring are your duty. The upside is that everything you learn about it transfers to your whole stack, because Redis is already running your cache and pub/sub. With RabbitMQ, the broker is a separate, hardened component with its own operational practice; the cost is running and knowing it. Neither is pilot-error — they price operational attention differently.
A decision rule that fits on a card
- Node.js services, Redis already in the stack, workloads shaped as jobs: BullMQ. Most product workloads fit, and queue-per-class covers fairness (Interactive and batch work never starve each other).
- Services in different languages needing protocol-level routing: RabbitMQ.
- Replayable event logs, stream processing, or multi-region fan-out: neither — that is Kafka territory.
My default for a NestJS team starting today: BullMQ with bounded retries and per-class queues, and revisit only when a concrete requirement crosses the card above. RealStream shipped its full production queue layer on one Redis instance in 60 days from first commit, and nothing in the interim suggested a broker would have been cheaper. If you are designing a queue layer right now and want a second opinion, I consult on exactly this — reach out by Telegram or email.
FAQ
Is BullMQ or RabbitMQ faster?
The useful question is workload fit, not microbenchmarks. BullMQ handles tens of thousands of jobs per minute on a single Redis node; RabbitMQ comfortably handles comparable broker throughput. Speed differences at those levels almost never decide real projects: retry policy, queue-per-class fairness, and operational ownership do.
Do we need RabbitMQ for a NestJS microservice setup?
Not by default if all services are Node.js and you already run Redis: BullMQ gives you job semantics and priorities with one less component. RabbitMQ earns its place when services are polyglot or when protocol-level routing and delivery guarantees are actual requirements rather than assumptions.
What are the main risks of a Redis-backed queue like BullMQ?
Concentration of responsibility: the Redis node carries the job layer, so persistence configuration, replication or a managed instance, maxmemory policy, and monitoring must be deliberate rather than default. Get those right (as documented in the BullMQ ops guides) and a single managed Redis reliably supports production queue layers like RealStream's thousands of concurrent jobs.
When should we skip both BullMQ and RabbitMQ and use Kafka?
When you need replayable event logs, exactly-once semantics across services, stream processing, or multi-region fan-out. Those requirements justify running a log-based system. Most teams debating RabbitMQ versus Kafka on paper do not have any of the four yet; measure the workload first.