Overview
Every BullMQ class (Queue, Worker, QueueEvents) requires a connection to Redis. BullMQ uses ioredis under the hood, and connection options are passed directly to the ioredis constructor.
If no connection options are provided, BullMQ defaults to localhost:6379.
Connection Options
BullMQ accepts connection configuration through the ConnectionOptions interface:
interface ConnectionOptions {
host ?: string ; // Default: '127.0.0.1'
port ?: number ; // Default: 6379
username ?: string ;
password ?: string ;
db ?: number ; // Database index
maxRetriesPerRequest ?: number | null ;
retryStrategy ?: ( times : number ) => number ;
url ?: string ; // Redis URL (e.g., redis://localhost:6379)
// ... other ioredis options
}
Basic Connection
Basic
URL Format
With Authentication
import { Queue , Worker } from 'bullmq' ;
const queue = new Queue ( 'myqueue' , {
connection: {
host: 'localhost' ,
port: 6379 ,
},
});
Reusing Connections
You can share an existing ioredis instance across multiple Queue instances to reduce connection overhead:
import { Queue } from 'bullmq' ;
import IORedis from 'ioredis' ;
const connection = new IORedis ({
host: 'localhost' ,
port: 6379 ,
maxRetriesPerRequest: null ,
});
// Reuse the connection
const queue1 = new Queue ( 'queue1' , { connection });
const queue2 = new Queue ( 'queue2' , { connection });
Workers and QueueEvents create additional blocking connections internally, even when reusing connections.
Connection Behavior
Queue vs Worker Connections
The connection requirements differ between producers and consumers:
Queue (Producer)
Worker (Consumer)
Use Case : Adding jobs via HTTP endpoints or API callsconst queue = new Queue ( 'myqueue' , {
connection: {
host: 'localhost' ,
port: 6379 ,
// Keep default maxRetriesPerRequest (20)
// Fast failure for user-facing operations
},
});
For producers, use the default maxRetriesPerRequest setting so operations fail quickly if Redis is unavailable. Use Case : Background job processingimport IORedis from 'ioredis' ;
const connection = new IORedis ({
host: 'localhost' ,
port: 6379 ,
maxRetriesPerRequest: null , // Retry indefinitely
});
const worker = new Worker ( 'myqueue' , async ( job ) => {
// Process job
}, { connection });
Workers should set maxRetriesPerRequest: null to keep retrying forever during temporary Redis outages.
Important Configuration
maxRetriesPerRequest
This setting controls how many times ioredis retries a failed command:
null (recommended for Workers): Retry indefinitely
Number (recommended for Queues): Retry N times before throwing an error
BullMQ will throw an exception if maxRetriesPerRequest is not null when passing a manual Redis client to Worker instances.
Redis Server Configuration
Ensure your Redis instance has the following setting: maxmemory-policy=noeviction
This prevents automatic key eviction which would cause unexpected errors in BullMQ.
Key Prefix
Do not use ioredis’s keyPrefix option. It is incompatible with BullMQ. Instead, use BullMQ’s built-in prefix option: const queue = new Queue ( 'myqueue' , {
prefix: 'myapp' , // Use this ✓
connection: {
// Do NOT use keyPrefix here ✗
},
});
Advanced Connection Options
Retry Strategy
Customize the retry backoff behavior:
const queue = new Queue ( 'myqueue' , {
connection: {
host: 'localhost' ,
port: 6379 ,
retryStrategy ( times : number ) {
// Exponential backoff: 1s, 2s, 4s, 8s, ..., max 20s
return Math . min ( times * 1000 , 20000 );
},
},
});
Redis Cluster
Connect to a Redis cluster:
import { Cluster } from 'ioredis' ;
import { Queue } from 'bullmq' ;
const cluster = new Cluster ([
{ host: 'redis-node-1' , port: 6379 },
{ host: 'redis-node-2' , port: 6379 },
{ host: 'redis-node-3' , port: 6379 },
], {
redisOptions: {
password: 'your-password' ,
},
});
const queue = new Queue ( 'myqueue' , { connection: cluster });
Connection Lifecycle
The RedisConnection class manages connection state:
// Connection states
type ConnectionStatus = 'initializing' | 'ready' | 'closing' | 'closed' ;
Waiting for Ready
All BullMQ classes expose a waitUntilReady() method:
const queue = new Queue ( 'myqueue' , { connection: { ... } });
// Wait for Redis connection to be established
await queue . waitUntilReady ();
// Now safe to use
await queue . add ( 'job' , { data: 'value' });
Closing Connections
Always close connections gracefully:
const queue = new Queue ( 'myqueue' , { connection: { ... } });
const worker = new Worker ( 'myqueue' , async ( job ) => {}, { connection: { ... } });
// Graceful shutdown
await worker . close ();
await queue . close ();
Version Requirements
Minimum Redis Version : 5.0.0
Recommended Redis Version : 6.2.0 or higher
BullMQ supports alternative Redis implementations:
Dragonfly : Full support
Valkey : Full support
Connection Events
Listen to connection events:
const queue = new Queue ( 'myqueue' , { connection: { ... } });
queue . on ( 'error' , ( err ) => {
console . error ( 'Redis connection error:' , err );
});
queue . on ( 'ready' , () => {
console . log ( 'Redis connection ready' );
});
queue . on ( 'close' , () => {
console . log ( 'Redis connection closed' );
});
Best Practices
Use Connection Pooling Reuse connections when possible to reduce overhead, but create separate connections for blocking operations.
Set maxRetriesPerRequest Use null for workers (background) and a number for queues (foreground).
Configure Redis Properly Set maxmemory-policy=noeviction and ensure sufficient memory.
Monitor Connections Track connection health and implement proper error handling.
Next Steps
Queues Learn how to create and manage queues
Workers Process jobs with workers