agenda vs bee-queue vs bree vs bull vs kue vs node-resque
Job and Queue Management
agendabee-queuebreebullkuenode-resqueSimilar Packages:

Job and Queue Management

Job and Queue Management Libraries in Node.js provide tools for handling background tasks, scheduling jobs, and managing queues of tasks to be processed asynchronously. These libraries help improve application performance by offloading time-consuming tasks from the main event loop, allowing for better scalability and responsiveness. They offer features like job prioritization, retries, scheduling, and monitoring, making them essential for building efficient and reliable applications that handle asynchronous processing. These libraries are particularly useful for tasks like sending emails, processing images, or performing data migrations without blocking the main application flow.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
agenda09,649297 kB211 days agoMIT
bee-queue04,026107 kB474 months agoMIT
bree03,28592 kB292 months agoMIT
bull016,245309 kB148a year agoMIT
kue09,457-2889 years agoMIT
node-resque01,410708 kB232 months agoApache-2.0

Feature Comparison: agenda vs bee-queue vs bree vs bull vs kue vs node-resque

Storage Backend

  • agenda:

    agenda uses MongoDB as its storage backend, which allows for persistent job storage, scheduling, and retrieval. This makes it suitable for applications that require long-term job storage and reliability, as jobs can be stored even if the application restarts.

  • bee-queue:

    bee-queue uses Redis as its storage backend, providing fast and ephemeral job storage. It is designed for low-latency job processing, making it ideal for applications that need quick job execution without the overhead of persistent storage.

  • bree:

    bree does not require any external storage backend, as it uses worker threads to execute jobs directly. This makes it lightweight and efficient for running jobs in memory, but it does not provide persistent job storage or queuing.

  • bull:

    bull uses Redis as its storage backend, offering both persistent and ephemeral job storage. It provides advanced features like job retries, delayed jobs, and rate limiting, making it suitable for applications that require robust queue management and reliability.

  • kue:

    kue uses Redis as its storage backend, providing persistent job storage with support for job prioritization and retries. It also includes a built-in UI for monitoring job progress, making it suitable for applications that need visual management of job queues.

  • node-resque:

    node-resque supports multiple storage backends, including Redis and MongoDB, allowing for flexible job storage options. It provides features like job scheduling, retries, and plugins, making it a versatile choice for applications that require a customizable queue system.

Job Scheduling

  • agenda:

    agenda supports advanced job scheduling, including recurring jobs, delayed jobs, and one-time jobs. It allows for flexible scheduling using cron-like syntax, making it suitable for applications that require complex scheduling capabilities.

  • bee-queue:

    bee-queue focuses on simple job queuing and does not provide built-in support for job scheduling. It is designed for fast, on-demand job processing rather than scheduled tasks.

  • bree:

    bree supports job scheduling using cron syntax, allowing for both one-time and recurring jobs. It leverages worker threads for executing scheduled jobs, providing better performance for CPU-intensive tasks.

  • bull:

    bull supports job scheduling, including delayed jobs and recurring jobs (with additional plugins). It provides a robust queuing mechanism with support for job prioritization and retries, making it suitable for complex job workflows.

  • kue:

    kue supports job scheduling with delayed jobs and prioritization. It allows for creating jobs with specific delay times and priority levels, making it suitable for applications that require controlled job execution.

  • node-resque:

    node-resque supports job scheduling, including delayed jobs and recurring jobs, through its flexible API. It allows for creating jobs with specified delays and supports custom scheduling logic, making it a versatile choice for time-based job execution.

UI and Monitoring

  • agenda:

    agenda does not provide a built-in UI for monitoring jobs, but it allows for integration with external monitoring tools. Developers can create custom dashboards to visualize job status and metrics using the data stored in MongoDB.

  • bee-queue:

    bee-queue provides a simple API for monitoring job status, but it does not include a built-in UI. Developers can create custom monitoring solutions using the provided API to track job progress and failures.

  • bree:

    bree does not include a built-in UI for monitoring jobs, but it provides detailed logging and event hooks that can be used to track job execution. Developers can integrate third-party monitoring tools for better visibility.

  • bull:

    bull does not provide a built-in UI for monitoring jobs, but it allows for integration with external monitoring tools. Developers can create custom dashboards to visualize job status and metrics using the data stored in Redis.

  • kue:

    kue includes a built-in UI for monitoring job queues, displaying job status, progress, and failure rates. The UI provides a visual representation of job queues, making it easy to manage and monitor jobs in real-time.

  • node-resque:

    node-resque does not provide a built-in UI, but it allows for integration with external monitoring tools. Developers can create custom dashboards to visualize job status and metrics using the data stored in the chosen backend.

Job Retries

  • agenda:

    agenda supports job retries in case of failure, allowing developers to configure retry logic and failure handling. It provides hooks for handling failed jobs and implementing custom retry strategies.

  • bee-queue:

    bee-queue supports job retries with configurable retry limits. It allows for automatic retries of failed jobs, making it suitable for handling transient errors in job processing.

  • bree:

    bree supports job retries through custom implementation, but it does not provide built-in retry functionality. Developers can implement their own retry logic using the provided job events and hooks.

  • bull:

    bull supports advanced job retries with configurable retry limits, backoff strategies, and failure handling. It provides robust support for handling failed jobs and implementing complex retry logic.

  • kue:

    kue supports job retries with configurable retry limits and failure handling. It allows for automatic retries of failed jobs, making it suitable for handling errors and ensuring job completion.

  • node-resque:

    node-resque supports job retries with configurable retry limits and backoff strategies. It provides flexible failure handling and allows for custom retry logic to be implemented.

Ease of Use: Code Examples

  • agenda:

    Simple Job Scheduling with agenda

    const Agenda = require('agenda');
    const mongoConnectionString = 'mongodb://localhost:27017/agenda';
    const agenda = new Agenda({ db: { address: mongoConnectionString } });
    
    // Define a job
    agenda.define('send email', async (job) => {
      console.log('Sending email...');
    });
    
    // Schedule a job
    agenda.schedule('in 10 seconds', 'send email');
    
    // Start the agenda
    agenda.start();
    
  • bee-queue:

    Simple Job Queue with bee-queue

    const Queue = require('bee-queue');
    const queue = new Queue('my-queue');
    
    // Process jobs
    queue.process(async (job) => {
      console.log(`Processing job ${job.id}`);
    });
    
    // Add a job to the queue
    queue.createJob({ data: 'my data' }).save();
    
  • bree:

    Simple Job Scheduling with bree

    const Bree = require('bree');
    const bree = new Bree({
      jobs: [{
        name: 'my-job',
        interval: '10s',
      }],
    });
    
    // Start the scheduler
    bree.start();
    
  • bull:

    Simple Job Queue with bull

    const Queue = require('bull');
    const myQueue = new Queue('my-queue');
    
    // Process jobs
    myQueue.process(async (job) => {
      console.log(`Processing job ${job.id}`);
    });
    
    // Add a job to the queue
    myQueue.add({ data: 'my data' });
    
  • kue:

    Simple Job Queue with kue

    const kue = require('kue');
    const queue = kue.createQueue();
    
    // Create a job
    const job = queue.create('email', { to: 'example@example.com' }).save();
    
    // Process the job
    queue.process('email', (job, done) => {
      console.log(`Sending email to ${job.data.to}`);
      done();
    });
    
  • node-resque:

    Simple Job Queue with node-resque

    const { Queue, Worker } = require('node-resque');
    const queue = new Queue({
      myQueue: { jobs: ['myJob'] },
    });
    const worker = new Worker({ queue });
    
    // Define a job
    worker.on('myJob', (job, done) => {
      console.log(`Processing job ${job.id}`);
      done();
    });
    
    // Start the worker
    worker.start();
    

How to Choose: agenda vs bee-queue vs bree vs bull vs kue vs node-resque

  • agenda:

    Choose agenda if you need a job scheduler with MongoDB integration that supports recurring jobs, delayed jobs, and job prioritization. It is ideal for applications that require flexible scheduling and persistence of job states.

  • bee-queue:

    Choose bee-queue if you need a simple and lightweight queue system with Redis support, focusing on performance and low latency. It is suitable for applications that require fast job processing with minimal overhead.

  • bree:

    Choose bree if you want a modern job scheduler that uses worker threads for executing jobs, providing better performance and resource utilization. It is ideal for applications that need to run CPU-intensive tasks without blocking the event loop.

  • bull:

    Choose bull if you need a feature-rich queue system with Redis support that offers advanced features like job retries, rate limiting, and delayed jobs. It is suitable for applications that require robust queue management and scalability.

  • kue:

    Choose kue if you need a priority job queue backed by Redis with a built-in UI for monitoring jobs. It is ideal for applications that require visual monitoring and management of job queues.

  • node-resque:

    Choose node-resque if you need a flexible and extensible job queue system that supports multiple backends (Redis, MongoDB, etc.) and provides features like job scheduling, retries, and plugins. It is suitable for applications that require a highly customizable queue system.

README for agenda

Agenda

Agenda

A light-weight job scheduling library for Node.js

NPM Version NPM Downloads

Migrating from v5? See the Migration Guide for all breaking changes.

Agenda 6.x

Agenda 6.x is a complete TypeScript rewrite with a focus on modularity and flexibility:

  • Pluggable storage backends - Choose from MongoDB, PostgreSQL, Redis, or implement your own. Each backend is a separate package - install only what you need.

  • Pluggable notification channels - Move beyond polling with real-time job notifications via Redis, PostgreSQL LISTEN/NOTIFY, or other pub/sub systems. Jobs get processed immediately when saved, not on the next poll cycle.

  • Modern stack - ESM-only, Node.js 18+, full TypeScript with strict typing.

See the 6.x Roadmap for details and progress.

Features

  • Minimal overhead job scheduling
  • Pluggable storage backends (MongoDB, PostgreSQL, Redis)
  • TypeScript support with full typing
  • Scheduling via cron or human-readable syntax
  • Configurable concurrency and locking
  • Real-time job notifications (optional)
  • Sandboxed worker execution via fork mode
  • TypeScript decorators for class-based job definitions

Installation

Install the core package and your preferred backend:

# For MongoDB
npm install agenda @agendajs/mongo-backend

# For PostgreSQL
npm install agenda @agendajs/postgres-backend

# For Redis
npm install agenda @agendajs/redis-backend

Requirements:

  • Node.js 18+
  • Database of your choice (MongoDB 4+, PostgreSQL, or Redis)

Quick Start

import { Agenda } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';

const agenda = new Agenda({
  backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
});

// Define a job
agenda.define('send email', async (job) => {
  const { to, subject } = job.attrs.data;
  await sendEmail(to, subject);
});

// Start processing
await agenda.start();

// Schedule jobs
await agenda.every('1 hour', 'send email', { to: 'user@example.com', subject: 'Hello' });
await agenda.schedule('in 5 minutes', 'send email', { to: 'admin@example.com', subject: 'Report' });
await agenda.now('send email', { to: 'support@example.com', subject: 'Urgent' });

Official Backend Packages

PackageBackendNotificationsInstall
@agendajs/mongo-backendMongoDBPolling onlynpm install @agendajs/mongo-backend
@agendajs/postgres-backendPostgreSQLLISTEN/NOTIFYnpm install @agendajs/postgres-backend
@agendajs/redis-backendRedisPub/Subnpm install @agendajs/redis-backend

Backend Capabilities

BackendStorageNotificationsNotes
MongoDB (MongoBackend)Storage only. Combine with external notification channel for real-time.
PostgreSQL (PostgresBackend)Full backend. Uses LISTEN/NOTIFY for notifications.
Redis (RedisBackend)Full backend. Uses Pub/Sub for notifications.
InMemoryNotificationChannelNotifications only. For single-process/testing.

Backend Configuration

MongoDB

import { Agenda } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';

// Via connection string
const agenda = new Agenda({
  backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
});

// Via existing MongoDB connection
const agenda = new Agenda({
  backend: new MongoBackend({ mongo: existingDb })
});

// With options
const agenda = new Agenda({
  backend: new MongoBackend({
    mongo: db,
    collection: 'jobs'        // Collection name (default: 'agendaJobs')
  }),
  processEvery: '30 seconds', // Job polling interval
  maxConcurrency: 20,         // Max concurrent jobs
  defaultConcurrency: 5       // Default per job type
});

PostgreSQL

import { Agenda } from 'agenda';
import { PostgresBackend } from '@agendajs/postgres-backend';

const agenda = new Agenda({
  backend: new PostgresBackend({
    connectionString: 'postgresql://user:pass@localhost:5432/mydb'
  })
});

Redis

import { Agenda } from 'agenda';
import { RedisBackend } from '@agendajs/redis-backend';

const agenda = new Agenda({
  backend: new RedisBackend({
    connectionString: 'redis://localhost:6379'
  })
});

Real-Time Notifications

For faster job processing across distributed systems:

import { Agenda, InMemoryNotificationChannel } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';

const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  notificationChannel: new InMemoryNotificationChannel()
});

Mixing Storage and Notification Backends

You can use MongoDB for storage while using a different system for real-time notifications:

import { Agenda } from 'agenda';
import { MongoBackend } from '@agendajs/mongo-backend';
import { RedisBackend } from '@agendajs/redis-backend';

// MongoDB for storage + Redis for real-time notifications
const redisBackend = new RedisBackend({ connectionString: 'redis://localhost:6379' });
const agenda = new Agenda({
  backend: new MongoBackend({ mongo: db }),
  notificationChannel: redisBackend.notificationChannel
});

This is useful when you want MongoDB's proven durability and flexible queries for job storage, but need faster real-time notifications across multiple processes.

API Overview

Defining Jobs

// Simple async handler
agenda.define('my-job', async (job) => {
  console.log('Processing:', job.attrs.data);
});

// With options
agenda.define('my-job', async (job) => { /* ... */ }, {
  concurrency: 10,
  lockLimit: 5,
  lockLifetime: 10 * 60 * 1000, // 10 minutes
  priority: 'high'
});

Defining Jobs with Decorators

For a class-based approach, use TypeScript decorators:

import { JobsController, Define, Every, registerJobs, Job } from 'agenda';

@JobsController({ namespace: 'email' })
class EmailJobs {
  @Define({ concurrency: 5 })
  async sendWelcome(job: Job<{ userId: string }>) {
    console.log('Sending welcome to:', job.attrs.data.userId);
  }

  @Every('1 hour')
  async cleanupBounced(job: Job) {
    console.log('Cleaning up bounced emails');
  }
}

registerJobs(agenda, [new EmailJobs()]);
await agenda.start();

// Schedule using namespaced name
await agenda.now('email.sendWelcome', { userId: '123' });

See Decorators Documentation for full details.

Scheduling Jobs

// Run immediately
await agenda.now('my-job', { userId: '123' });

// Run at specific time
await agenda.schedule('tomorrow at noon', 'my-job', data);
await agenda.schedule(new Date('2024-12-25'), 'my-job', data);

// Run repeatedly
await agenda.every('5 minutes', 'my-job');
await agenda.every('0 * * * *', 'my-job'); // Cron syntax

Job Control

// Cancel jobs matching a filter (removes from database)
await agenda.cancel({ name: 'my-job' });
await agenda.cancel({ name: 'my-job', data: { userId: 123 } });

// Cancel ALL jobs unconditionally
await agenda.cancelAll();

// Disable/enable jobs globally (by query)
await agenda.disable({ name: 'my-job' });  // Disable all jobs matching query
await agenda.enable({ name: 'my-job' });   // Enable all jobs matching query

// Disable/enable individual jobs
const job = await agenda.create('my-job', data);
job.disable();
await job.save();

// Progress tracking
agenda.define('long-job', async (job) => {
  for (let i = 0; i <= 100; i += 10) {
    await doWork();
    await job.touch(i); // Report progress 0-100
  }
});

Stopping / Draining

// Stop immediately - unlocks running jobs so other workers can pick them up
await agenda.stop();

// Drain - waits for running jobs to complete before stopping
await agenda.drain();

// Drain with timeout (30 seconds) - for cloud platforms with shutdown deadlines
const result = await agenda.drain(30000);
if (result.timedOut) {
    console.log(`${result.running} jobs still running after timeout`);
}

// Drain with AbortSignal - for external control
const controller = new AbortController();
setTimeout(() => controller.abort(), 30000);
await agenda.drain({ signal: controller.signal });

Use drain() for graceful shutdowns where you want in-progress jobs to finish their work.

Events

agenda.on('start', (job) => console.log('Job started:', job.attrs.name));
agenda.on('complete', (job) => console.log('Job completed:', job.attrs.name));
agenda.on('success', (job) => console.log('Job succeeded:', job.attrs.name));
agenda.on('fail', (err, job) => console.log('Job failed:', job.attrs.name, err));

// Job-specific events
agenda.on('start:send email', (job) => { /* ... */ });
agenda.on('fail:send email', (err, job) => { /* ... */ });

Custom Backend

For databases other than MongoDB, PostgreSQL, or Redis, implement AgendaBackend:

import { AgendaBackend, JobRepository } from 'agenda';

class SQLiteBackend implements AgendaBackend {
  readonly repository: JobRepository;
  readonly notificationChannel = undefined; // Or implement NotificationChannel

  async connect() { /* ... */ }
  async disconnect() { /* ... */ }
}

const agenda = new Agenda({
  backend: new SQLiteBackend({ path: './jobs.db' })
});

See Custom Backend Driver for details.

Documentation

Related Packages

Official Backend Packages:

Tools:

License

MIT