Task Queues for TypeScript: A Complete Guide to Bull and Bee-Queue
When developing modern web applications in TypeScript, there is often a need to perform long-running or resource-intensive operations asynchronously without blocking the main thread. For example: sending email notifications, generating PDF reports, processing images, or synchronizing with external APIs. Task queues (job queues) are used to solve these problems. In this article, we will take a detailed look at the two most popular libraries for TypeScript — Bull and Bee-Queue, and also analyze how to integrate them into your project.
Why are task queues needed?
A task queue allows you to:
- Separate responsibilities — the main service is only responsible for adding a task, while the handler is responsible for its execution.
- Manage load — you can limit the number of concurrent tasks.
- Guarantee delivery — tasks are not lost even if the process crashes (thanks to Redis).
- Schedule execution — delay a task for a specific time or repeat it on a schedule.
- Handle errors — automatic retries with exponential backoff.
Bull — The Most Popular Queue for Node.js and TypeScript
Bull is a powerful Redis-based library that supports a full set of features: priorities, retries, delays, pauses, events, and monitoring. Bull has excellent TypeScript typings.
Installation and Setup
npm install bull @types/bullA simple example of a queue for sending email:
import Queue from 'bull';
interface EmailJob { to: string; subject: string; body: string;}
// Create a queue named 'email'const emailQueue = new Queue<EmailJob>('email', { redis: { host: 'localhost', port: 6379 }, defaultJobOptions: { attempts: 3, // up to 3 attempts backoff: { type: 'exponential', delay: 2000 }, removeOnComplete: true, }});
// Handler — runs in the backgroundemailQueue.process(async (job) => { console.log(`Sending email to ${job.data.to}`); // Simulate sending await new Promise(resolve => setTimeout(resolve, 1000)); console.log(`Email sent: ${job.data.subject}`);});
// Add a taskasync function addEmail() { await emailQueue.add({ to: 'user@example.com', subject: 'Hello from the queue!', body: 'This is a test email.', });}
addEmail();Advanced Bull Features
- Recurring jobs (cron):
queue.add(data, { repeat: { cron: '0 8 * * *' } }) - Priorities:
queue.add(data, { priority: 1 })— the lower the number, the higher the priority. - Delayed execution:
queue.add(data, { delay: 60000 })— delay by 1 minute. - Events: you can subscribe to
completed,failed,progress, and others. - Pause/Resume:
queue.pause()/queue.resume().
// Event handlingemailQueue.on('completed', (job, result) => { console.log(`Job ${job.id} completed`);});
emailQueue.on('failed', (job, err) => { console.error(`Job ${job.id} failed: ${err.message}`);});Bee-Queue — A Lightweight Alternative
Bee-Queue is a minimalist Redis-based queue that is simpler and faster than Bull in terms of memory consumption. It is suitable for small projects or cases where complex configuration is not needed.
Installation and Example
npm install bee-queueimport Bee from 'bee