Profiles·Public

bullmq

semver>=5.0.0 <6.0.0postconditions23functions21last verified2026-06-23coverage score100%

Postconditions: what we check

  • add · queue-add-redis-error
    error
    WhenRedis connection fails or is down during add operation
    ThrowsError with Redis connection failure details
    Required handlingCaller MUST wrap Queue.add() in try-catch to handle Redis connection errors. Redis downtime crashes application if unhandled. Use try-catch to gracefully degrade or retry.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • addBulk · queue-addbulk-redis-error
    error
    WhenRedis connection fails during bulk operation
    ThrowsError causing partial or complete bulk operation failure
    Required handlingCaller MUST wrap Queue.addBulk() in try-catch to handle Redis errors. Bulk operations can partially fail if Redis connection is lost - must handle to prevent data loss.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • process · worker-process-job-error
    warning
    Whenjob processing throws error or promise rejects
    ThrowsError causing job to fail and trigger retry logic if configured
    Required handlingWorker processor SHOULD handle job errors gracefully with try-catch to control retry behavior and provide meaningful error messages. Unhandled errors in processor can cause worker to stop processing subsequent jobs.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • close · close-error
    warning
    Whenconnection close operation fails (timeout, Redis error)
    ThrowsError during connection cleanup
    Required handlingCaller SHOULD handle close() errors during graceful shutdown to ensure proper cleanup. Use try-catch in shutdown handlers to log but not crash on close errors.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • run · worker-run-no-error-listener
    error
    WhenWorker started without 'error' event listener attached
    ThrowsUnhandled Error event from EventEmitter when Redis errors occur
    Required handlingCaller MUST attach worker.on('error', handler) BEFORE calling worker.run(). Without an error listener, Node.js throws an unhandled error event that crashes the process. The BullMQ docs explicitly warn: 'If the error handler is missing, your worker may stop processing jobs when an error is emitted.'
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • run · worker-run-redis-connection-error
    error
    WhenRedis connection fails during worker main loop
    ThrowsError emitted via 'error' event on worker instance
    Required handlingCaller MUST wrap Worker usage with error event listeners. Redis connection loss during run() causes the worker to emit 'error' events. Without maxRetriesPerRequest set to null for consumers, the worker will throw after retry limit is reached.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][4]
  • FlowProducer.add · flow-add-redis-error
    error
    WhenRedis connection fails during atomic flow addition
    ThrowsError with Redis connection failure details
    Required handlingCaller MUST wrap FlowProducer.add() in try-catch. Flow additions are atomic (all-or-nothing) via Redis transactions, but Redis connection failure during the transaction causes the entire flow to fail. Without error handling, background pipeline orchestration silently stops.
    costhighin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[5]
  • FlowProducer.addBulk · flow-addbulk-redis-error
    error
    WhenRedis connection fails during bulk flow addition
    ThrowsError with Redis connection failure details
    Required handlingCaller MUST wrap FlowProducer.addBulk() in try-catch. Bulk flow additions are atomic — Redis failure loses all flows in the batch. Must handle to prevent silent pipeline breakage.
    costhighin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[5]
  • upsertJobScheduler · scheduler-upsert-redis-error
    error
    WhenRedis connection fails during scheduler upsert
    ThrowsError with Redis connection failure details
    Required handlingCaller MUST wrap upsertJobScheduler() in try-catch. Scheduler creation failure means recurring jobs silently stop being produced. This is especially dangerous during deployment — if scheduler registration fails, no cron jobs run until the next successful registration.
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[6]
  • pause · queue-pause-redis-error
    warning
    WhenRedis connection fails during pause operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap pause() in try-catch. Pause failure during maintenance windows means jobs continue processing when they should be stopped. Handle errors to verify pause actually took effect.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1]
  • resume · queue-resume-redis-error
    warning
    WhenRedis connection fails during resume operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap resume() in try-catch. Resume failure means the queue stays paused — jobs accumulate in waiting state without being processed. Must verify resume succeeded.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1]
  • obliterate · queue-obliterate-active-jobs-error
    error
    WhenQueue has active jobs and force option is not set
    ThrowsError indicating queue cannot be obliterated with active jobs
    Required handlingCaller MUST wrap obliterate() in try-catch. The method throws if there are active jobs and force=false. Additionally, this is an iterative SCAN-based operation — large queues may fail mid-obliteration on Redis errors, leaving the queue in a partially destroyed state.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • waitUntilFinished · job-wait-until-finished-timeout
    error
    WhenJob does not complete within the specified TTL
    ThrowsError indicating job timed out
    Required handlingCaller MUST wrap waitUntilFinished() in try-catch. The promise rejects on both job failure AND timeout. Using waitUntilFinished() in request-response patterns (e.g., HTTP handler waits for job result) without timeout handling causes hung requests. Always set a TTL parameter.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • waitUntilFinished · job-wait-until-finished-job-failed
    error
    WhenThe job fails during processing
    ThrowsError with the job's failedReason
    Required handlingCaller MUST handle rejection from waitUntilFinished(). When the job's processor throws, this promise rejects with the failure reason. Without try-catch, the calling code gets an unhandled rejection.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • Job.remove · job-remove-locked-error
    error
    WhenJob is currently being processed by a worker (locked)
    ThrowsError indicating job is locked and cannot be removed
    Required handlingCaller MUST wrap job.remove() in try-catch. Active jobs have locks and cannot be removed — the method throws rather than silently failing. Handle this to implement retry-after-completion logic.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[7]
  • Job.retry · job-retry-invalid-state
    error
    WhenJob is not in failed or completed state, or job does not exist
    ThrowsError indicating job cannot be retried (wrong state, locked, or missing)
    Required handlingCaller MUST wrap job.retry() in try-catch. The method throws if the job is locked, does not exist, or is not in a finished state. Handle errors to avoid crashing retry-management code.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[8]
  • clean · queue-clean-redis-error
    warning
    WhenRedis connection fails during clean operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap clean() in try-catch. Clean operations run Lua scripts against Redis — connection failures leave the queue in an inconsistent state. Handle errors in maintenance/cron code to prevent silent cleanup failures.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1]
  • drain · queue-drain-redis-error
    warning
    WhenRedis connection fails during drain operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap drain() in try-catch. Drain failure during deployment/maintenance means stale jobs remain in queue. Handle to verify drain completed.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1]
  • retryJobs · queue-retryjobs-redis-error
    warning
    WhenRedis connection fails during batch retry operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap retryJobs() in try-catch. Batch retry operations iterate over potentially large job sets — Redis failure mid-iteration causes partial retries. Handle to track which jobs were actually retried.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[8]
  • promoteJobs · queue-promotejobs-redis-error
    warning
    WhenRedis connection fails during batch promote operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap promoteJobs() in try-catch. Like retryJobs(), this iterates over potentially large delayed-job sets via Redis Lua scripts. Connection loss mid-iteration leaves jobs partially promoted — some in waiting, others still delayed — with no way for the caller to know how many transitioned. Handle to track and resume promotion.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[9]
  • removeOrphanedJobs · queue-removeorphanedjobs-redis-error
    error
    WhenRedis connection fails during SCAN-based iteration
    ThrowsError with Redis connection failure details
    Required handlingCaller MUST wrap removeOrphanedJobs() in try-catch. The method runs an iterative SCAN+Lua loop over the entire queue keyspace and a connection failure mid-loop leaves orphans behind without returning a count. The d.ts comment recommends calling it in a while-loop with a limit to bound iteration; combine with try-catch so the loop can resume from cursor 0 after a transient Redis failure rather than crashing the migration script.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[10]
  • rateLimit · queue-ratelimit-redis-error
    warning
    WhenRedis connection fails during limiter SET operation
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap rateLimit() in try-catch. The method writes a single Redis SET on the limiter key — failure means the runtime throttle was never applied. In flows where rateLimit() is called in response to an upstream 429 (e.g. third-party API rate limit), a swallowed Redis error leads to continued requests against the upstream and an extended rate-limit ban.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[11]
  • setGlobalConcurrency · queue-setglobalconcurrency-redis-error
    warning
    WhenRedis connection fails during HSET on the meta hash
    ThrowsError with Redis connection failure details
    Required handlingCaller SHOULD wrap setGlobalConcurrency() in try-catch. Failure means the global concurrency limit was never persisted — workers continue at the prior limit (or unbounded if it was never set). Common deployment failure: a startup hook calls setGlobalConcurrency() to clamp workers during a downstream incident; a swallowed Redis error means the clamp never takes effect and the downstream gets overrun.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[12]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: bullmq

Package: bullmq Version: 5.70.1 Category: queue (Redis-based job queue and message queue)


Official Documentation

Homepage: https://bullmq.io/ Repository: https://github.com/taskforcesh/bullmq npm: https://www.npmjs.com/package/bullmq

Key Documentation Sections


Behavioral Requirements

Error Handling

Redis Connection Errors:

  • Queue.add() can fail if Redis is down or connection is lost
  • Must wrap Queue operations in try-catch blocks
  • Use enableOfflineQueue: false to fail fast instead of queuing commands
  • Set maxRetriesPerRequest: 1 for faster failure detection

Job Processing Errors:

  • Worker automatically moves jobs to "failed" status if processor throws
  • Unhandled errors can cause worker to stop processing jobs
  • Must handle errors in worker processor to keep queue running
  • Default retry: 3 times, then moves to dead letter queue

Error Events:

  • Attach handlers for error event on Queue and Worker instances
  • Listen to failed event with worker.on('failed', (job, err) => {...})

Sources:

Resource Management

Connection Cleanup:

  • Every BullMQ class consumes at least one Redis connection
  • Must call .close() on Queue and Worker instances to release connections
  • Connection leaks can exhaust Redis max clients limit
  • Cleanup is especially important in HTTP endpoints that create queues

Connection Reuse:

  • Queue and Worker can accept existing ioredis instances
  • QueueScheduler and QueueEvents require blocking connections (cannot reuse)
  • Shared connections improve resource utilization

Sources:

Common Mistakes

1. Not Handling Redis Disconnections:

  • Assuming Redis is always available
  • Solution: Wrap Queue.add() in try-catch, handle connection errors

2. Ignoring Worker Error Events:

  • Worker stops processing when error event is not handled
  • Solution: Always attach error event handlers

3. Not Closing Connections:

  • Creating Queue instances in HTTP endpoints without cleanup
  • Solution: Reuse Queue instances or always call .close()

4. Improper Error Handling in Processors:

  • Try-catch in processor prevents automatic retry mechanism
  • Solution: Let errors throw naturally unless you need custom handling

5. Missing Retry Configuration:

  • Not configuring retry attempts for critical jobs
  • Solution: Set retry options when adding jobs

Sources:


CVE Analysis

No known behavioral CVEs as of 2026-02-25.

Checked: CVE Database

BullMQ is actively maintained with regular security updates. Primary risks are:

  • Operational: Redis connection failures
  • Misconfiguration: Improper error handling leading to queue blocking

Real-World Examples

Real-world examples of proper usage:

  1. GitHub Code Search: bullmq examples
  2. Official Examples: BullMQ Examples Repository
  3. Medium Articles: Message Queue in Node.js with BullMQ and Redis
  4. Production Patterns: How to Process Scheduled Queue Jobs

Contract Rationale

Why these contracts matter:

Problem Prevention

  1. Application Crashes from Redis Failures:

    • Without error handling, Redis connection failures crash the entire application
    • Jobs queued via HTTP endpoints need immediate failure feedback
    • Contract ensures graceful degradation when Redis is unavailable
  2. Queue Blocking from Worker Errors:

    • Unhandled errors in worker processors can stop the entire queue
    • Other jobs wait indefinitely while worker is stuck
    • Contract ensures workers handle errors and continue processing
  3. Connection Leaks:

    • Creating Queue/Worker instances in HTTP endpoints without cleanup
    • Exhausts Redis connection pool over time
    • Contract enforces proper connection management

Consequences of Violations

Severity: ERROR (Redis Connection Failures)

  • Impact: Immediate application crash
  • Frequency: Common in production (network issues, Redis restarts)
  • Cost: Service outages, lost user requests
  • Example: HTTP endpoint creating queue without try-catch → 500 error cascade

Severity: WARNING (Worker Error Handling)

  • Impact: Queue stops processing, jobs pile up
  • Frequency: Moderate (depends on job complexity)
  • Cost: Delayed processing, SLA violations
  • Example: Email worker crashes → thousands of undelivered emails

Severity: WARNING (Connection Cleanup)

  • Impact: Gradual resource exhaustion
  • Frequency: High in microservices with many queue instances
  • Cost: Redis connection limit reached, new connections fail
  • Example: 1000 requests/minute × unclosed connections → Redis maxed out in 10 minutes

Why Critical for Production

BullMQ is typically used for:

  • Critical background jobs (payments, emails, notifications)
  • High-throughput systems (thousands of jobs per minute)
  • Distributed systems (multiple workers, multiple queues)
  • User-facing features (job status tracking, real-time updates)

Production characteristics:

  • Redis failures are inevitable (network issues, maintenance, scaling)
  • Worker errors will happen (external API failures, data issues)
  • Connection management at scale (100+ instances in microservices)

Without these contracts:

  • ❌ Application becomes fragile to Redis issues
  • ❌ Queue processing can halt unexpectedly
  • ❌ Resource leaks degrade system over time
  • ❌ Recovery requires manual intervention

With these contracts:

  • ✅ Graceful degradation during Redis failures
  • ✅ Workers continue processing despite individual job errors
  • ✅ Clean resource management at scale
  • ✅ Self-healing system design

Created: 2026-02-25 Status: ✅ COMPLETE - Ready for production use

Need a different package?
Request a profile