Skip to main content
The most important method of the Queue class is add, which allows you to add jobs to the queue in different ways.

Basic Usage

Adding a job is straightforward:
import { Queue } from 'bullmq';

const queue = new Queue('paint');

await queue.add('paint-job', { color: 'red' });
The job will now be stored in Redis, waiting for a worker to pick it up and process it. Workers may not be running when you add the job, but as soon as one worker is connected to the queue, it will pick up the job and process it.

Method Signature

async add(
  name: string,
  data: T,
  opts?: JobsOptions
): Promise<Job>
name
string
required
Name of the job to be added to the queue
data
T
Arbitrary data to append to the job. This will be available in the worker’s processor function.
opts
JobsOptions
Job options that affect how the job is processed. See below for available options.

Job Options

Timing Options

opts.delay
number
default:"0"
An amount of milliseconds to wait until this job can be processed. The job will be in the “delayed” state until the delay expires.
await queue.add('paint', { color: 'blue' }, { delay: 5000 });
opts.timestamp
number
default:"Date.now()"
Timestamp when the job was created

Priority

opts.priority
number
default:"0"
Ranges from 0 (highest priority) to 2,097,152 (lowest priority). Note that using priorities has a slight impact on performance, so only use it if required.
await queue.add('urgent', { task: 'critical' }, { priority: 1 });

Retry Options

opts.attempts
number
default:"1"
The total number of attempts to try the job until it completes
await queue.add('flaky-task', { data: 'test' }, { attempts: 3 });
opts.backoff
number | BackoffOptions
Backoff setting for automatic retries if the job fails. Can be a number (milliseconds) or an object with type and delay.
// Simple backoff (fixed delay)
await queue.add('task', { data: 'test' }, { 
  attempts: 3,
  backoff: 5000 // 5 seconds between retries
});

// Exponential backoff
await queue.add('task', { data: 'test' }, {
  attempts: 5,
  backoff: {
    type: 'exponential',
    delay: 1000
  }
});

Auto-Removal Options

opts.removeOnComplete
boolean | number | KeepJobs
If true, removes the job when it successfully completes. When given a number, it specifies the maximum amount of jobs to keep. You can also provide an object specifying max age and/or count to keep.
// Remove immediately after completion
await queue.add('temp-job', { data: 'test' }, { removeOnComplete: true });

// Keep last 1000 completed jobs
await queue.add('job', { data: 'test' }, { removeOnComplete: 1000 });

// Keep jobs up to 1 hour old, max 1000 jobs
await queue.add('job', { data: 'test' }, {
  removeOnComplete: {
    age: 3600, // seconds
    count: 1000
  }
});
opts.removeOnFail
boolean | number | KeepJobs
If true, removes the job when it fails after all attempts. When given a number, it specifies the maximum amount of jobs to keep. You can also provide an object specifying max age and/or count to keep.
// Keep last 5000 failed jobs for debugging
await queue.add('risky-job', { data: 'test' }, { 
  removeOnComplete: 1000,
  removeOnFail: 5000 
});

Job Identification

opts.jobId
string
Override the job ID. By default, the job ID is a unique integer, but you can use this setting to override it. If you use this option, it is up to you to ensure the jobId is unique. If you attempt to add a job with an ID that already exists, it will not be added (a ‘duplicated’ event will be emitted instead).
await queue.add('idempotent-job', { userId: 123 }, { 
  jobId: 'user-123-sync'
});
JobId cannot be ‘0’ or start with ‘0:‘

Processing Options

opts.lifo
boolean
default:"false"
If true, adds the job to the right of the queue instead of the left, making it a LIFO (Last In First Out) queue.
await queue.add('stack-task', { data: 'test' }, { lifo: true });

Logging Options

opts.keepLogs
number
Maximum amount of log entries that will be preserved for this job
opts.stackTraceLimit
number
Limits the amount of stack trace lines that will be recorded in the stacktrace when the job fails

Size Limits

opts.sizeLimit
number
Limits the size in bytes of the job’s data payload (as a JSON serialized string)

Parent-Child Jobs

opts.parent
ParentOptions
Parent options for creating parent-child job relationships. Allows you to create flows where child jobs must complete before the parent job can proceed.
await queue.add('child-job', { data: 'test' }, {
  parent: {
    id: 'parent-job-id',
    queue: 'parent-queue'
  }
});

Repeatable Jobs

opts.repeat
RepeatOptions
Repeat this job based on a cron schedule or interval.
// Cron-based repeat
await queue.add('daily-report', { date: new Date() }, {
  repeat: {
    pattern: '0 9 * * *' // Every day at 9 AM
  }
});

// Interval-based repeat
await queue.add('health-check', {}, {
  repeat: {
    every: 60000 // Every minute
  }
});

Complete Example

import { Queue } from 'bullmq';

const queue = new Queue('notifications');

// Add a job with multiple options
const job = await queue.add(
  'send-email',
  {
    to: '[email protected]',
    subject: 'Welcome!',
    body: 'Thanks for signing up'
  },
  {
    attempts: 3,
    backoff: {
      type: 'exponential',
      delay: 1000
    },
    removeOnComplete: {
      age: 3600,
      count: 1000
    },
    removeOnFail: {
      age: 86400
    },
    priority: 2
  }
);

console.log(`Job added with ID: ${job.id}`);

Build docs developers (and LLMs) love