bullmq vs bull
Job Queues and Background Processing
bullmqbullSimilar Packages:

Job Queues and Background Processing

bull and bullmq are powerful libraries for managing job queues in Node.js applications. They allow developers to offload tasks to be processed asynchronously, improving application performance and responsiveness. Both libraries are built on Redis and provide features like job scheduling, retries, and concurrency control. However, bullmq is the newer version, designed to be more modular and efficient, with a focus on modern JavaScript features and improved performance. It also supports advanced features like delayed jobs, rate limiting, and better handling of job events, making it a more suitable choice for new projects that require scalability and flexibility.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
bullmq1,737,0298,5952.34 MB34811 days agoMIT
bull652,45616,251309 kB147a year agoMIT

Feature Comparison: bullmq vs bull

Architecture

  • bullmq:

    bullmq introduces a modular architecture, allowing developers to use only the parts they need. This design improves performance and scalability, making it more suitable for large applications with complex job processing requirements.

  • bull:

    bull follows a monolithic architecture, where all features are bundled together. This makes it easy to use but can lead to limitations in flexibility and scalability for very large applications.

Performance

  • bullmq:

    bullmq is designed for high performance, with optimizations that reduce latency and improve throughput. It is better suited for applications that require processing a large number of jobs quickly and efficiently.

  • bull:

    bull is performant for most use cases, but it can experience bottlenecks in scenarios with extremely high job throughput or complex job processing logic.

Feature Set

  • bullmq:

    bullmq offers a richer feature set, including advanced scheduling, rate limiting, and improved event handling. It also supports delayed jobs and has a more flexible API, making it easier to implement complex job processing logic.

  • bull:

    bull provides a comprehensive set of features for job processing, including retries, scheduling, and concurrency control. However, it lacks some of the more advanced features found in bullmq, such as rate limiting and better event handling.

Documentation and Community

  • bullmq:

    bullmq is newer but comes with thorough documentation and is actively maintained. Its modern design and features have attracted a growing community, making it a promising choice for future development.

  • bull:

    bull has extensive documentation and a large community, which makes it easy to find resources and support. It is a well-established library with a proven track record.

Ease of Use: Code Examples

  • bullmq:

    Basic Job Queue with bullmq

    const { Queue } = require('bullmq');
    const myQueue = new Queue('my-queue');
    
    myQueue.process(async (job) => {
      console.log(`Processing job ${job.id}: ${job.data}`);
    });
    
    myQueue.add('my-job', { some: 'data' });
    
  • bull:

    Basic Job Queue with bull

    const Queue = require('bull');
    const myQueue = new Queue('my-queue');
    
    myQueue.process(async (job) => {
      console.log(`Processing job ${job.id}: ${job.data}`);
    });
    
    myQueue.add({ some: 'data' });
    

How to Choose: bullmq vs bull

  • bullmq:

    Choose bullmq if you are starting a new project and need a more modern and feature-rich solution. It offers better performance, modular architecture, and advanced features that make it ideal for applications with high scalability requirements.

  • bull:

    Choose bull if you are working on an existing project that already uses it, or if you need a stable and well-documented library for job processing. It is suitable for most use cases and has a large community and ecosystem.

README for bullmq




The fastest, most reliable, Redis-based distributed queue for Node.
Carefully written for rock solid stability and atomicity.

Read the documentation

Follow Us for *important* Bull/BullMQ/BullMQ-Pro news and updates!

πŸ›  Tutorials

You can find tutorials and news in this blog: https://blog.taskforce.sh/

News πŸš€

🌐 Language agnostic BullMQ

Do you need to work with BullMQ on platforms other than Node.js? If so, check out the BullMQ Proxy

Official FrontEnd

Taskforce.sh, Inc

Supercharge your queues with a professional front end:

  • Get a complete overview of all your queues.
  • Inspect jobs, search, retry, or promote delayed jobs.
  • Metrics and statistics.
  • and many more features.

Sign up at Taskforce.sh

πŸš€ Sponsors πŸš€

Dragonfly Dragonfly is a new Redisβ„’ drop-in replacement that is fully compatible with BullMQ and brings some important advantages over Redisβ„’ such as massive better performance by utilizing all CPU cores available and faster and more memory efficient data structures. Read more here on how to use it with BullMQ.

Used by

Some notable organizations using BullMQ:

Microsoft Vendure Datawrapper Nest Langfuse
Curri Novu NoCodeDB Infisical

The gist

Install:

$ yarn add bullmq

Add jobs to the queue:

import { Queue } from 'bullmq';

const queue = new Queue('Paint');

queue.add('cars', { color: 'blue' });

Process the jobs in your workers:

import { Worker } from 'bullmq';

const worker = new Worker('Paint', async job => {
  if (job.name === 'cars') {
    await paintCar(job.data.color);
  }
});

Listen to jobs for completion:

import { QueueEvents } from 'bullmq';

const queueEvents = new QueueEvents('Paint');

queueEvents.on('completed', ({ jobId }) => {
  console.log('done painting');
});

queueEvents.on(
  'failed',
  ({ jobId, failedReason }: { jobId: string; failedReason: string }) => {
    console.error('error painting', failedReason);
  },
);

Adds jobs with parent-child relationship:

import { FlowProducer } from 'bullmq';

const flow = new FlowProducer();

const originalTree = await flow.add({
  name: 'root-job',
  queueName: 'topQueueName',
  data: {},
  children: [
    {
      name: 'child-job',
      data: { idx: 0, foo: 'bar' },
      queueName: 'childrenQueueName',
      children: [
        {
          name: 'grandchild-job',
          data: { idx: 1, foo: 'bah' },
          queueName: 'grandChildrenQueueName',
        },
        {
          name: 'grandchild-job',
          data: { idx: 2, foo: 'baz' },
          queueName: 'grandChildrenQueueName',
        },
      ],
    },
    {
      name: 'child-job',
      data: { idx: 3, foo: 'foo' },
      queueName: 'childrenQueueName',
    },
  ],
});

This is just scratching the surface, check all the features and more in the official documentation

Feature Comparison

Since there are a few job queue solutions, here is a table comparing them:

FeatureBullMQ-ProBullMQBullKueBeeAgenda
Backendredisredisredisredisredismongo
Observablesβœ“
Group Rate Limitβœ“
Group Supportβœ“
Batches Supportβœ“
Parent/Child Dependenciesβœ“βœ“
Deduplication (Debouncing)βœ“βœ“βœ“
Deduplication (Throttling)βœ“βœ“βœ“
Prioritiesβœ“βœ“βœ“βœ“βœ“
Concurrencyβœ“βœ“βœ“βœ“βœ“βœ“
Delayed jobsβœ“βœ“βœ“βœ“βœ“
Global eventsβœ“βœ“βœ“βœ“
Rate Limiterβœ“βœ“βœ“
Pause/Resumeβœ“βœ“βœ“βœ“
Sandboxed workerβœ“βœ“βœ“
Repeatable jobsβœ“βœ“βœ“βœ“
Atomic opsβœ“βœ“βœ“βœ“
Persistenceβœ“βœ“βœ“βœ“βœ“βœ“
UIβœ“βœ“βœ“βœ“βœ“
Optimized forJobs / MessagesJobs / MessagesJobs / MessagesJobsMessagesJobs

Contributing

Fork the repo, make some changes, submit a pull-request! Here is the contributing doc that has more details.

Thanks

Thanks for all the contributors that made this library possible, also a special mention to Leon van Kammen that kindly donated his npm bullmq repo.