How to Build a Background Job Queue in Node.js with BullMQ and Redis
A job queue lets your Node.js app hand slow or heavy tasks off to be processed in the background, so your web requests stay fast and responsive. Sending email, processing images, generating reports — none of it should make a user wait. BullMQ, backed by Redis, is a robust way to do this.
Why use a job queue?
- Fast responses — reply to the user immediately, do the heavy work after.
- Reliability — jobs persist in Redis, so they survive restarts and can retry on failure.
- Control — limit concurrency so background work does not overwhelm your system.
How it works
Your app (the producer) adds jobs to a queue. Separate worker processes (consumers) pull jobs and process them. Redis stores the queue in between, so producers and workers are decoupled.
Adding jobs
const queue = new Queue('emails', { connection });
await queue.add('welcome', { userId: 42 });
Processing jobs
new Worker('emails', async job => { await sendEmail(job.data); }, { connection });
Run workers as separate processes — often on their own server or instance — so heavy jobs never compete with your web traffic.
Handling failures and retries
Configure automatic retries with backoff so transient failures (a temporarily down email service) recover on their own. Failed jobs can be inspected and retried. Log outcomes with structured logging and watch queue depth as part of monitoring.
Common uses
Email and notifications, image and video processing, report generation, data imports, scheduled recurring jobs, and calling slow third-party APIs — anything you would rather not do inside a request.
Frequently asked questions
Why not just use setTimeout or run the task inline?
Inline work blocks the request; setTimeout work is lost if the process restarts. A queue persists jobs in Redis, retries failures, and processes them in dedicated workers — far more reliable.
Should workers run separately from my web app?
Ideally yes — running workers as their own processes (or on their own server) keeps heavy background work from competing with web requests for CPU and memory.
Does a job queue need Redis?
BullMQ uses Redis to store and coordinate jobs, which is what gives it persistence and reliability. You will need a Redis instance available to your app and workers.
Was this article helpful?