agenda vs bee-queue vs bree vs bull vs kue vs node-resque
Node.js 任务队列库
agendabee-queuebreebullkuenode-resque类似的npm包:

Node.js 任务队列库

任务队列库用于处理异步任务和作业调度,允许开发者将任务推送到队列中,随后由工作进程异步执行。这些库提供了可靠的任务管理、调度和重试机制,适用于需要处理大量后台任务的应用程序。它们可以帮助提高应用程序的性能和响应能力,确保任务的顺序执行和失败重试。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
agenda09,649297 kB211 天前MIT
bee-queue04,026107 kB474 个月前MIT
bree03,28592 kB292 个月前MIT
bull016,245309 kB1481 年前MIT
kue09,457-2889 年前MIT
node-resque01,410708 kB232 个月前Apache-2.0

功能对比: agenda vs bee-queue vs bree vs bull vs kue vs node-resque

任务调度

  • agenda:

    Agenda 提供了强大的任务调度功能,支持定时和重复任务,可以使用 cron 表达式进行灵活调度,非常适合需要定期执行的任务。

  • bee-queue:

    Bee-Queue 主要专注于任务的快速处理,虽然不支持复杂的调度功能,但其高性能使其在处理短小任务时表现出色。

  • bree:

    Bree 支持 cron 表达式,可以轻松设置定时任务,适合需要定期执行的场景。

  • bull:

    Bull 提供了强大的任务调度功能,支持延迟和重复任务,能够处理复杂的任务流,适合需要高可靠性的应用。

  • kue:

    Kue 提供了简单的任务调度功能,支持延迟任务和优先级设置,适合需要可视化管理的应用。

  • node-resque:

    Node-Resque 支持多种调度方式,能够与 Redis 集成,适合需要高可用性的分布式任务处理。

性能

  • agenda:

    Agenda 的性能依赖于 MongoDB 的性能,适合处理较少的高频任务,但在高并发场景下可能会受到限制。

  • bee-queue:

    Bee-Queue 以高性能著称,特别适合处理大量短小任务,能够快速入队和出队,适合高并发场景。

  • bree:

    Bree 的性能良好,适合定时任务的调度,能够有效管理工作进程。

  • bull:

    Bull 提供了高性能的任务处理能力,能够处理复杂的任务流,适合需要高可靠性的应用。

  • kue:

    Kue 的性能较为稳定,适合中等规模的任务处理,提供了良好的监控界面。

  • node-resque:

    Node-Resque 的性能取决于 Redis 的性能,适合需要高可用性和分布式处理的场景。

易用性

  • agenda:

    Agenda 提供了简单易用的 API,易于集成到现有应用中,适合初学者使用。

  • bee-queue:

    Bee-Queue 的设计简单,易于上手,适合快速开发和部署。

  • bree:

    Bree 提供了直观的 API,易于使用,适合需要快速实现定时任务的开发者。

  • bull:

    Bull 提供了丰富的功能和灵活的 API,适合需要复杂任务管理的开发者,但学习曲线相对较陡。

  • kue:

    Kue 提供了易于使用的 API 和可视化界面,适合需要监控任务状态的开发者。

  • node-resque:

    Node-Resque 提供了简单的 API,易于与 Redis 集成,适合需要高可用性的开发者。

监控与管理

  • agenda:

    Agenda 不提供内置的监控工具,开发者需要自行实现监控功能。

  • bee-queue:

    Bee-Queue 提供了简单的监控功能,但不如其他库丰富。

  • bree:

    Bree 提供了基本的任务管理和监控功能,适合简单的任务调度。

  • bull:

    Bull 提供了强大的监控和管理功能,能够实时查看任务状态和进度,适合需要详细监控的应用。

  • kue:

    Kue 提供了丰富的监控界面,能够实时查看任务的状态和历史记录,适合需要可视化管理的应用。

  • node-resque:

    Node-Resque 提供了基本的监控功能,适合需要与 Redis 集成的开发者。

社区支持

  • agenda:

    Agenda 拥有活跃的社区支持,文档齐全,适合开发者查阅和学习。

  • bee-queue:

    Bee-Queue 的社区相对较小,但文档清晰,易于理解。

  • bree:

    Bree 的社区正在成长,文档逐步完善,适合新手使用。

  • bull:

    Bull 拥有强大的社区支持,文档丰富,适合需要深入学习的开发者。

  • kue:

    Kue 的社区活跃,文档详细,适合开发者快速上手。

  • node-resque:

    Node-Resque 拥有良好的社区支持,适合需要与 Redis 集成的开发者。

如何选择: agenda vs bee-queue vs bree vs bull vs kue vs node-resque

  • agenda:

    选择 Agenda 如果你需要一个基于 MongoDB 的任务调度器,支持定时任务和重复任务,且易于集成到现有的应用程序中。它适合需要灵活调度的场景。

  • bee-queue:

    选择 Bee-Queue 如果你需要一个轻量级、高性能的任务队列,特别是在需要快速处理大量短小任务时。它的设计简单,适合高并发的场景。

  • bree:

    选择 Bree 如果你需要一个简单易用的任务调度库,支持 cron 表达式,并且可以轻松管理工作进程。它适合需要定时任务的应用。

  • bull:

    选择 Bull 如果你需要一个功能强大的任务队列,支持优先级、延迟任务和重复任务,且能够处理复杂的任务流。它适合需要高可靠性和可扩展性的场景。

  • kue:

    选择 Kue 如果你需要一个易于使用的任务队列,提供丰富的 UI 界面来监控任务状态,适合需要可视化管理的应用。

  • node-resque:

    选择 Node-Resque 如果你需要一个与 Redis 兼容的任务队列,支持多种后端和工作进程管理,适合需要高可用性和分布式处理的场景。

agenda的README

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