Skip to main content
By default, BullMQ keeps completed and failed jobs in Redis indefinitely. Auto-removal strategies help manage Redis memory by automatically cleaning up finalized jobs.

Why Auto-removal?

Without auto-removal:
  • Memory bloat: Completed/failed jobs accumulate in Redis
  • Performance degradation: Large sets slow down Redis operations
  • Cost increase: More Redis memory required
With auto-removal:
  • Controlled memory usage: Keep only recent or important jobs
  • Better performance: Smaller Redis sets
  • Cost efficiency: Optimal Redis sizing

Configuration Options

Configure auto-removal on the Worker options:

removeOnComplete

Control how completed jobs are removed:

removeOnFail

Control how failed jobs are removed:
A common practice is to keep fewer completed jobs and more failed jobs for debugging purposes.

Removal Strategies

Remove All Jobs

Remove jobs immediately after completion:
Jobs are removed regardless of their names. All completed/failed jobs will be deleted.
Use case: High-volume queues where job results aren’t needed after processing.

Keep a Fixed Number of Jobs

Keep the most recent N jobs:
How it works:
  • When job #1001 completes, job #1 is removed
  • Keeps a rolling window of recent jobs
  • Maintains a fixed memory footprint

Keep Jobs by Age

Keep jobs up to a certain age (in seconds):
Time units:
  • 3600 = 1 hour
  • 24 * 3600 = 24 hours
  • 7 * 24 * 3600 = 7 days

Combine Age and Count

Use both strategies for more control:
Behavior: Keeps jobs that satisfy BOTH conditions.

Control Cleanup Performance

Limit the number of jobs removed per cleanup iteration:
Use case: Prevent cleanup operations from blocking Redis for too long.

KeepJobs Type Reference

The KeepJobs type supports two formats:

Auto-removal Behavior

Lazy Cleanup

Auto-removal works lazily. Jobs are only removed when a new job completes or fails, triggering the cleanup process.
Implications:
  • If no jobs are processing, no cleanup happens
  • Cleanup is distributed across job completions
  • No dedicated cleanup background process

Per-job Cleanup

Each job completion/failure triggers a cleanup:

Production Examples

High-Volume Queue

Keep minimal history:

Audit Trail Queue

Keep jobs longer for compliance:

Development Queue

Keep everything for debugging:

Critical Queue

Balance debugging and memory:

Monitoring Auto-removal

Track job counts to verify cleanup:

Manual Cleanup

For one-time or scheduled cleanup:

Best Practices

1

Keep fewer completed jobs

Completed jobs are usually less interesting than failures:
2

Use age-based removal for compliance

When regulatory requirements dictate retention periods:
3

Set cleanup limits for high-volume queues

Prevent cleanup from blocking Redis:
4

Monitor job counts

Alert when counts exceed expected thresholds.
5

Test in staging first

Verify removal settings don’t delete needed jobs.
6

Consider external archiving

For long-term storage, export jobs before removal:

Troubleshooting

Jobs Not Being Removed

Cause: No jobs completing/failing to trigger cleanup. Solution: Ensure workers are actively processing:

Too Many Jobs Accumulating

Cause: Cleanup settings too lenient or no cleanup configured. Solution: Adjust removal settings:

Redis Memory Still Growing

Cause: Jobs accumulating in other states (delayed, waiting, active). Solution: Monitor and clean other job states:

Worker Options

Configure worker behavior

Queue Management

Manage jobs in queues

Job Lifecycle

Understand job states

Redis Optimization

Optimize Redis usage

API Reference