Node.js7 min read

Message Queues with Bull

Handle background jobs with Bull and Redis. Process tasks asynchronously.

Sarah Chen
December 19, 2025
0.0k0

Message Queues with Bull

Background jobs are essential for time-consuming tasks. Bull makes it easy with Redis.

Setup

npm install bull

Make sure Redis is running:

redis-server

Basic Queue

const Queue = require('bull');

const emailQueue = new Queue('email', {
  redis: {
    host: '127.0.0.1',
    port: 6379
  }
});

async function sendWelcomeEmail(userId, email) {
  await emailQueue.add({
    userId,
    email,
    type: 'welcome'
  });
}

emailQueue.process(async (job) => {
  const { userId, email, type } = job.data;
  
  console.log(`Sending ${type} email to ${email}`);
  
  await sendEmail(email);
  
  return { sent: true };
});

await sendWelcomeEmail(123, 'user@example.com');

What happens:

  1. Job added to queue
  2. Worker picks up job
  3. Processes asynchronously
  4. Main app continues without waiting

Real Example: Image Processing

const Queue = require('bull');
const sharp = require('sharp');

const imageQueue = new Queue('image-processing');

app.post('/upload', upload.single('image'), async (req, res) => {
  await imageQueue.add({
    filename: req.file.filename,
    path: req.file.path
  });
  
  res.json({ message: 'Processing started' });
});

imageQueue.process(async (job) => {
  const { path, filename } = job.data;
  
  await sharp(path)
    .resize(800, 600)
    .toFile(`uploads/resized-${filename}`);
  
  await sharp(path)
    .resize(200, 200)
    .toFile(`uploads/thumb-${filename}`);
  
  return { processed: true };
});

Job Events

emailQueue.on('completed', (job, result) => {
  console.log(`Job ${job.id} completed`, result);
});

emailQueue.on('failed', (job, err) => {
  console.error(`Job ${job.id} failed`, err);
});

emailQueue.on('progress', (job, progress) => {
  console.log(`Job ${job.id} is ${progress}% done`);
});

Job Options

await emailQueue.add(data, {
  attempts: 3,
  backoff: {
    type: 'exponential',
    delay: 2000
  }
});

await emailQueue.add(data, {
  delay: 5000
});

await emailQueue.add(data, {
  priority: 1
});

await emailQueue.add(data, {
  removeOnComplete: true,
  removeOnFail: false
});

Scheduled Jobs

await emailQueue.add(data, {
  repeat: {
    cron: '0 9 * * *'
  }
});

await emailQueue.add(data, {
  repeat: {
    every: 5 * 60 * 1000
  }
});

Multiple Workers

imageQueue.process(5, async (job) => {
  await processImage(job.data);
});

Processes 5 jobs concurrently.

Key Takeaway

Bull handles background jobs with Redis. Add jobs to queue, process asynchronously. Automatic retries and scheduling. Perfect for emails, image processing, reports.

#Node.js#Bull#Redis#Queue#Jobs