Skip to main content

Queue.add()

Creates a new job and adds it to the queue. If the queue is empty, the job will be executed directly. Otherwise, it will be placed in the queue and executed as soon as possible.

Signature

add(name?: string, data: object, opts?: JobOpts): Promise<Job>

Parameters

name
string
Optional name for the job (also called job type). Only process functions defined for this name will process the job.
data
object
required
The job data. This object will be available as job.data in the processor function.
opts
JobOpts
Job options.
priority
number
Priority value ranging from 1 (highest) to MAX_INT (lowest). Using priorities has a slight performance impact.
delay
number
Milliseconds to wait before this job can be processed. For accurate delays, ensure server and client clocks are synchronized.
attempts
number
Total number of attempts to try the job until it completes.
repeat
RepeatOpts
Repeat job according to a schedule.
cron
string
Cron expression for the schedule.
tz
string
Timezone for cron expression.
startDate
Date | string | number
Start date when the repeat job should start (only with cron).
endDate
Date | string | number
End date when the repeat job should stop repeating.
limit
number
Number of times the job should repeat at maximum.
every
number
Repeat every X milliseconds. Cannot be used with cron setting.
count
number
Start value for the repeat iteration count.
backoff
number | BackoffOpts
Backoff setting for automatic retries if the job fails. Requires attempts to be set.As number: Delay in milliseconds using fixed strategy.As object:
type
string
Backoff type: ‘fixed’, ‘exponential’, or custom strategy name.
delay
number
Backoff delay in milliseconds.
options
any
Options for custom backoff strategies.
lifo
boolean
default:"false"
If true, adds the job to the right of the queue (LIFO) instead of the left (FIFO).
timeout
number
Number of milliseconds after which the job should fail with a timeout error.
jobId
number | string
Override the job ID. By default, the job ID is a unique integer. You must ensure uniqueness when using this option.
removeOnComplete
boolean | number | KeepJobs
If true, removes the job when it successfully completes. A number specifies the count of jobs to keep.KeepJobs interface:
age
number
Maximum age in seconds for job to be kept.
count
number
Maximum count of jobs to be kept.
removeOnFail
boolean | number | KeepJobs
If true, removes the job when it fails after all attempts. A number specifies the count of jobs to keep.
stackTraceLimit
number
Limits the number of stack trace lines recorded in the stacktrace.

Returns

job
Promise<Job>
A promise that resolves to the created Job instance.

Examples

Basic Job

const job = await queue.add({ email: '[email protected]' });
console.log(`Job created with ID: ${job.id}`);

Named Job

await queue.add('email', {
  to: '[email protected]',
  subject: 'Welcome!',
  body: 'Thanks for signing up'
});

Delayed Job

// Process after 5 seconds
await queue.add('reminder', { userId: 123 }, {
  delay: 5000
});

Job with Priority

// Higher priority (processed first)
await queue.add('urgent-task', { data: 'important' }, {
  priority: 1
});

// Lower priority
await queue.add('normal-task', { data: 'regular' }, {
  priority: 10
});

Job with Retry Logic

await queue.add('api-request', { url: 'https://api.example.com' }, {
  attempts: 3,
  backoff: {
    type: 'exponential',
    delay: 2000
  }
});

Repeating Job (Cron)

// Run every day at 3:00 AM
await queue.add('daily-report', { type: 'summary' }, {
  repeat: {
    cron: '0 3 * * *',
    tz: 'America/New_York'
  }
});

Repeating Job (Interval)

// Run every 30 seconds
await queue.add('health-check', { service: 'api' }, {
  repeat: {
    every: 30000
  }
});

Job with Timeout

await queue.add('long-task', { data: 'process' }, {
  timeout: 60000, // Fail if not completed in 60 seconds
  attempts: 2
});

Job with Custom ID

await queue.add('unique-task', { userId: 123 }, {
  jobId: 'user-123-daily-task'
});

Auto-cleanup Completed Jobs

await queue.add('temporary-task', { data: 'value' }, {
  removeOnComplete: true,
  removeOnFail: true
});

Keep Last N Jobs

await queue.add('logged-task', { data: 'value' }, {
  removeOnComplete: 100, // Keep last 100 completed
  removeOnFail: 50       // Keep last 50 failed
});

Keep Jobs by Age

await queue.add('archived-task', { data: 'value' }, {
  removeOnComplete: {
    age: 86400, // Keep for 24 hours (in seconds)
    count: 1000 // But maximum 1000 jobs
  }
});

LIFO Queue

// Add to front of queue (Last In, First Out)
await queue.add('priority-task', { data: 'urgent' }, {
  lifo: true
});

Queue.addBulk()

Creates multiple jobs and adds them to the queue in a single operation. This is more efficient than calling add() multiple times.

Signature

addBulk(jobs: { name?: string, data: object, opts?: JobOpts }[]): Promise<Job[]>

Parameters

jobs
array
required
Array of job specifications. Each job follows the same signature as Queue.add().

Returns

jobs
Promise<Job[]>
A promise that resolves to an array of created Job instances.

Examples

Bulk Add Multiple Jobs

const jobs = await queue.addBulk([
  { name: 'email', data: { to: '[email protected]' } },
  { name: 'email', data: { to: '[email protected]' } },
  { name: 'email', data: { to: '[email protected]' } }
]);

console.log(`Created ${jobs.length} jobs`);

Bulk Add with Options

await queue.addBulk([
  {
    name: 'process',
    data: { id: 1 },
    opts: { priority: 1 }
  },
  {
    name: 'process',
    data: { id: 2 },
    opts: { priority: 2 }
  },
  {
    name: 'process',
    data: { id: 3 },
    opts: { delay: 5000 }
  }
]);

Bulk Add from Database Records

const users = await db.getUsers();

const jobSpecs = users.map(user => ({
  name: 'welcome-email',
  data: {
    email: user.email,
    name: user.name
  },
  opts: {
    attempts: 3,
    backoff: 2000
  }
}));

await queue.addBulk(jobSpecs);

Important Notes

Job Cleanup: Completed and failed jobs are stored in Redis indefinitely by default. Use removeOnComplete and removeOnFail options to prevent Redis from running out of memory.
Named Jobs: You need to define processors for all named jobs you add, unless you use '*' as the processor name.
Repeatable Jobs: Adding a job with the repeat option creates a Repeatable Job configuration AND schedules the first run. Repeatable jobs are not included in methods like getJobs(). Use getRepeatableJobs() instead.
Job ID Uniqueness: When using jobId, repeated jobs with different repeat options can have the same ID, but regular jobs cannot share IDs.

Timeout Implementation

Jobs are NOT proactively stopped after the timeout. The job is marked as failed and the promise is rejected, but Bull cannot stop the processor function externally. To stop a job after timeout:
  • Have the job periodically check job.getState() and exit if status becomes ‘failed’
  • Implement the job as a cancelable promise with a cancel() method
  • Add a listener for the ‘failed’ event and stop the job externally

Build docs developers (and LLMs) love