BullMQ
The premium queue and job scheduling solution for Node.js, backed by Redis. Handles retries, rate limiting, priorities, repeatable jobs, and job dependencies out of the box.
Why BullMQ?
Background job processing in Node.js (email sending, PDF generation)
You need reliable job queues with retries and dead-letter queues
Already using Redis — BullMQ is zero-infra-overhead
Signal Breakdown
What drives the Trust Score
Download Trend
Last 12 months
Tradeoffs & Caveats
Know before you commitPython backend — Celery is the standard choice
Managed/serverless job scheduling — Trigger.dev or Inngest are simpler
Simple cron jobs — Vercel Cron or GitHub Actions are enough
Pricing
Free tier & paid plans
Open source, free forever (requires Redis)
N/A
MIT license
Alternative Tools
Other options worth considering
The most widely used distributed task queue for Python. Celery handles background jobs, scheduled tasks, and async processing using Redis or RabbitMQ as a broker. A staple of Django and Flask applications.
Open-source background job platform built for serverless and edge. Write durable background jobs as plain TypeScript functions with retries, delays, and scheduling — no infrastructure setup.
Often Used Together
Complementary tools that pair well with BullMQ
Learning Resources
Docs, videos, tutorials, and courses
Get Started
Repository and installation options
View on GitHub
github.com/taskforcesh/bullmq
npm install bullmqQuick Start
Copy and adapt to get going fast
import { Queue, Worker, Job } from 'bullmq';
import { Redis } from 'ioredis';
const connection = new Redis({ maxRetriesPerRequest: null });
const pdfQueue = new Queue<{ userId: string; reportId: string }>('pdf-reports', { connection });
const worker = new Worker<{ userId: string; reportId: string }>('pdf-reports', async (job: Job) => {
const { userId, reportId } = job.data;
const pdf = await generatePdf(reportId);
await uploadToS3(`reports/${userId}/${reportId}.pdf`, pdf);
await notifyUser(userId, 'Your report is ready!');
}, {
connection,
concurrency: 5,
defaultJobOptions: { attempts: 3, backoff: { type: 'exponential', delay: 1000 } },
});Code Examples
Common usage patterns
Repeatable cron job
Schedule a recurring job with BullMQ
import { Queue } from 'bullmq';
const reportQueue = new Queue('reports', { connection });
// Run every day at 9am UTC
await reportQueue.add(
'daily-digest',
{ type: 'digest' },
{ repeat: { pattern: '0 9 * * *' } }
);
console.log('Daily report job scheduled');Job with progress tracking
Track and report job progress
import { Worker, Job } from 'bullmq';
const worker = new Worker('import', async (job: Job) => {
const { rows } = job.data;
for (let i = 0; i < rows.length; i++) {
await processRow(rows[i]);
await job.updateProgress(Math.round((i + 1) / rows.length * 100));
}
}, { connection });
worker.on('progress', (job, progress) => {
console.log(`Job ${job.id} is ${progress}% complete`);
});Community Notes
Real experiences from developers who've used this tool