BullMQ
Part of the Backend Developer Roadmap
In short
Already using Redis? BullMQ turns it into a full job queue for Node, with retries, delays, priorities and scheduled jobs, in a few lines of TypeScript.
A popular Redis-backed job/message queue library for Node.js — simpler to set up than RabbitMQ or Kafka, and a common first choice for background jobs in a Node backend.

Think of it like this
The restaurant ticket rail
The waiter clips each order slip on the rail above the stove. Cooks pull slips in order, and if a dish burns, the slip goes back up to try again. A slip marked 'serve at 8' waits its turn. BullMQ is that rail, with Redis holding the slips.
Watch it happen
A job with retries
add welcome, attempts 3
1/5The API adds a job to the emails queue. BullMQ stores it in Redis as waiting.
The big ideas
What you need to know
Retries with backoff
Set attempts and backoff per job. Temporary failures heal on their own without you writing retry loops.
Delayed and scheduled jobs
Add a delay for 'remind in 1 hour', or set up repeating jobs for daily reports.
Concurrency
One worker can run several jobs at once with the concurrency option. Run more worker processes to scale further.
Redis is the store
Jobs live in Redis. Use a persistent Redis setup, or a crash can lose waiting jobs.
See it in code
Walk through the code
1import { Queue, Worker } from "bullmq";2 3const connection = { host: "localhost", port: 6379 };4export const emailQueue = new Queue("emails", { connection });5 6await emailQueue.add("welcome", { userId: 7 }, {7 attempts: 3,8 backoff: { type: "exponential", delay: 1000 },9});10 11new Worker("emails", async (job) => {12 await sendWelcomeEmail(job.data.userId);13}, { connection, concurrency: 5 });1/3A queue is a name plus a Redis connection. Producers and workers use the same name.
Run the Worker in a separate process from your API, so heavy jobs never slow down requests. Throwing inside the processor marks the job failed.
Save yourself the pain
Common mistakes
Oops
Putting a 5 MB PDF inside job data.
Do this instead
Store files in S3 or disk and put only the key or id in the job. Redis memory is precious.
Oops
Running Redis with an eviction policy like allkeys-lru for BullMQ.
Do this instead
Use noeviction, or Redis may silently delete your jobs when memory fills up.
Your mission
A flaky job that heals
Quick check
Your API and BullMQ worker run in the same process, and a CPU-heavy job slows every request. What's the usual fix?
Go deeper
- 1Set up a BullMQ queue and worker to process a background job, e.g. sending an email.
- 2Add retry logic with exponential backoff for failed jobs.
- 3Use BullMQ's dashboard (Bull Board) to monitor job status.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.