Skip to main content
BullMQ supports graceful job cancellation using the standard AbortController and AbortSignal APIs. This allows you to cancel jobs that are currently being processed and perform cleanup operations.

How Job Cancellation Works

When you cancel a job:
  1. The worker’s cancelJob() method aborts the signal passed to the processor
  2. The processor receives the abort event and can perform cleanup
  3. The processor should throw an error to mark the job as failed
  4. The job moves to the failed state (with or without retries, depending on error type)

Processor with Cancellation Support

Add the optional signal parameter to your processor function:
The processor function signature:
  • job: The job instance
  • token: Lock token for the job
  • signal: Optional AbortSignal for cancellation detection

Cancelling Jobs

Use the Worker class methods to cancel active jobs:

Getting Active Jobs

Find jobs to cancel:
Use the event-based approach for immediate response:

Why Event-Based?

Immediate response - No polling delay
More efficient - No CPU wasted checking in loops
Cleaner code - Separation of concerns
Standard pattern - Matches Web APIs like fetch()

Using with Native APIs

Many APIs natively support AbortSignal:
APIs that support AbortSignal:
  • fetch(url, { signal }) - HTTP requests
  • addEventListener(event, handler, { signal }) - Auto-removes listener on abort
  • Database clients (Postgres, MongoDB drivers)
  • File system operations (newer Node.js APIs)

Polling Pattern (Alternative)

Check signal.aborted periodically:
The polling pattern is simpler but less efficient than the event-based approach. Use it for simple loops or when you can’t use event listeners.

Cancellation with Cleanup

Perform async cleanup before failing the job:

Job State After Cancellation

With Regular Error (Will Retry)

Throw a regular Error to allow retries:
  • Job state: Moves to failed
  • Retries: Job WILL be retried if attempts remain
  • Use case: When you want the job to be retried later

With UnrecoverableError (No Retry)

Throw UnrecoverableError to prevent retries:
  • Job state: Moves to failed
  • Retries: Job will NOT be retried
  • Use case: When cancellation should be permanent

Handling Lock Renewal Failures

When a worker loses its lock, cancel the job gracefully:
When a worker loses the lock, it cannot move the job to failed state. The job remains active temporarily and will be moved back to waiting by the stalled job checker. This is correct behavior - trust BullMQ’s recovery mechanism.

Multi-Phase Work with Cancellation

Check cancellation at strategic points:

Cancelling Custom Operations

For operations without native AbortSignal support:

Backward Compatibility

Processors without signal handling still work:
The signal parameter is optional. Existing processors continue to work without modification.

Sandboxed Processors and Cancellation

Sandboxed processors automatically support cancellation:
See Sandboxed Processors for more details.

Best Practices

1

Use event-based cancellation

Attach abort event listener for immediate response.
2

Clean up resources

Always cleanup in the abort handler to prevent resource leaks.
3

Choose appropriate error type

Use UnrecoverableError for permanent cancellation, regular Error for retries.
4

Check cancellation at key points

In long-running jobs, check signal.aborted between phases.
5

Combine with timeouts

Use job options for timeout-based cancellation:
6

Handle cleanup errors gracefully

Catch errors during cleanup to avoid masking the cancellation.

Stalled Jobs

Understand lock renewal failures

Graceful Shutdown

Cancel jobs during shutdown

Sandboxed Processors

Cancel sandboxed jobs

Worker Options

Configure worker behavior

API Reference