by Noemi P.

BullMQ is a fast, reliable, Redis-backed distributed job queue for Node.js with official clients for Python, PHP, and Elixir. It supports priorities, delays, retries, rate limiting, and parent-child job dependencies.
BullMQ is a Redis-backed distributed job queue for Node.js that provides queues, workers, job scheduling, flow orchestration, and repeatable job support with atomic Lua-scripted operations. It targets backend engineers who need durable, reliable task processing across multiple processes or servers. The typical buyer integrates it into an existing Node.js/TypeScript service to offload work to background workers.
classes/ - Core classes: Queue, Worker, Job, JobScheduler, FlowProducer, QueueEvents, QueueGetters, RedisConnection, Repeat, Scripts, and supporting utilities.classes/errors/ - Typed error subclasses: DelayedError, RateLimitError, UnrecoverableError, WaitingChildrenError, WaitingError.commands/ - Lua script loader (ScriptLoader, scriptLoader) that compiles and uploads Redis scripts at startup.enums/ - Enumerations: ChildCommand, ErrorCode, MetricsTime, ParentCommand, TelemetryAttributes.interfaces/ - TypeScript interface definitions for options, job data shapes, queue metadata, connection config, and more.types/ - Shared type aliases, including the Processor type.utils/ - Internal utilities (childSend, createScripts, etc.) re-exported for advanced use.index.ts - Single barrel entry point that re-exports everything.version.ts - Package version constant.npm install ioredis bullmq
npm install --save-dev typescript @types/node
BullMQ bundles its own Lua scripts and ships as CommonJS-compatible ESM. No native build steps, no pod install, no prebuild required. A running Redis instance (6.2+ recommended, 7.x preferred) is the only external requirement.
Copy the source/ directory into your project, e.g. . Alternatively, just use the published npm package - the source block is the authoritative reference.
Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This TypeScript cli / script completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 8a94585aefe51c6a…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
src/bullmq-source/bullmqPoint tsconfig.json at the source if you need to compile it locally:
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"bullmq": ["./src/bullmq-source/index.ts"]
}
},
"include": ["src/**/*"]
}
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
import { Queue, Worker, Job, FlowProducer, QueueEvents } from 'bullmq';
'./bullmq-source' or the alias you configured in tsconfig.json.class Queue<DataType = any, ReturnType = any, NameType extends string = string>
extends QueueGetters<DataType, ReturnType, NameType> {
constructor(name: string, opts?: QueueOptions);
add(name: NameType, data: DataType, opts?: JobsOptions): Promise<Job<DataType, ReturnType, NameType>>;
addBulk(jobs: { name: NameType; data: DataType; opts?: BulkJobOptions }[]): Promise<Job[]>;
getJob(jobId: string): Promise<Job | undefined>;
pause(): Promise<void>;
resume(): Promise<void>;
close(): Promise<void>;
}
Use Queue to enqueue jobs from any producer process. Pass QueueOptions with a connection field pointing to your ioredis options. Call add to push a single job and addBulk for batches.
class Worker<DataType = any, ReturnType = any, NameType extends string = string>
extends MainWorker<DataType, ReturnType, NameType> {
constructor(
name: string,
processor: Processor<DataType, ReturnType, NameType> | string | null,
opts?: WorkerOptions,
);
on(event: 'completed', listener: (job: Job, result: ReturnType) => void): this;
on(event: 'failed', listener: (job: Job | undefined, error: Error) => void): this;
close(force?: boolean): Promise<void>;
}
Use Worker to consume jobs. The second argument is either an async function (inline processor) or a path string to a sandboxed child-process module. Attach completed and failed listeners for observability.
class FlowProducer extends MainBase {
constructor(opts?: QueueBaseOptions);
add(flow: FlowJob, opts?: FlowOpts): Promise<JobNode>;
addBulk(flows: FlowJob[], opts?: FlowOpts): Promise<JobNode[]>;
close(): Promise<void>;
}
Use FlowProducer when jobs have parent-child dependencies. A parent job waits in the waiting-children state until all its children complete. Nest FlowJob objects to declare the dependency tree declaratively.
class QueueEvents extends QueueBase {
constructor(name: string, opts?: QueueEventsOptions);
on(event: 'completed', listener: (args: { jobId: string; returnvalue: string }) => void): this;
on(event: 'failed', listener: (args: { jobId: string; failedReason: string }) => void): this;
on(event: 'progress', listener: (args: { jobId: string; data: number | object }) => void): this;
close(): Promise<void>;
}
Use QueueEvents in monitoring services or API servers to receive real-time job lifecycle events over a dedicated Redis connection without polling.
A minimal setup that enqueues an email job and processes it in a worker.
import { Queue, Worker, Job } from 'bullmq';
import IORedis from 'ioredis';
const connection = new IORedis({
host: process.env.REDIS_HOST ?? '127.0.0.1',
port: Number(process.env.REDIS_PORT ?? 6379),
maxRetriesPerRequest: null,
});
const emailQueue = new Queue('email', { connection });
// Producer: add a job
await emailQueue.add('send-welcome', { to: 'user@example.com', template: 'welcome' });
// Worker: process jobs
const worker = new Worker<{ to: string; template: string }>(
'email',
async (job: Job) => {
console.log(`Sending ${job.data.template} email to ${job.data.to}`);
// call your mailer here
},
{ connection },
);
worker.on('completed', (job) => console.log(`Job ${job.id} completed`));
worker.on('failed', (job, err) => console.error(`Job ${job?.id} failed:`, err.message));
Processes video: extract audio and generate thumbnail in parallel, then package only after both finish.
import { FlowProducer, FlowJob } from 'bullmq';
import IORedis from 'ioredis';
const connection = new IORedis({ host: '127.0.0.1', port: 6379, maxRetriesPerRequest: null });
const flow = new FlowProducer({ connection });
const tree = await flow.add({
name: 'package-video',
queueName: 'video-pipeline',
data: { videoId: 'abc123' },
children: [
{ name: 'extract-audio', queueName: 'video-pipeline', data: { videoId: 'abc123' } },
{ name: 'gen-thumbnail', queueName: 'video-pipeline', data: { videoId: 'abc123' } },
],
} as FlowJob);
console.log('Root job id:', tree.job.id);
await flow.close();
Schedules a report job to run every hour using a cron expression.
import { Queue } from 'bullmq';
import IORedis from 'ioredis';
const connection = new IORedis({ host: '127.0.0.1', port: 6379, maxRetriesPerRequest: null });
const reportQueue = new Queue('reports', { connection });
await reportQueue.upsertJobScheduler(
'hourly-report',
{ pattern: '0 * * * *' },
{
name: 'generate-report',
data: { type: 'sales' },
opts: { attempts: 3, backoff: { type: 'exponential', delay: 5000 } },
},
);
console.log('Scheduler registered');
await reportQueue.close();
Listens for completed and failed events without running a worker.
import { QueueEvents } from 'bullmq';
import IORedis from 'ioredis';
const connection = new IORedis({ host: '127.0.0.1', port: 6379, maxRetriesPerRequest: null });
const events = new QueueEvents('email', { connection });
events.on('completed', ({ jobId, returnvalue }) => {
console.log(`Job ${jobId} done, result:`, returnvalue);
});
events.on('failed', ({ jobId, failedReason }) => {
console.error(`Job ${jobId} failed:`, failedReason);
});
index.ts - Barrel re-export for the entire library; import everything from here.version.ts - Exports the current package version string.classes/queue.ts - Queue class: add, remove, pause, drain, and inspect jobs.classes/worker.ts - Worker class: polling loop, concurrency control, rate limiting, sandboxed processors.classes/job.ts - Job class: represents a single job instance with state transitions, progress updates, and retry logic.classes/job-scheduler.ts - JobScheduler: manages repeatable/cron job records in Redis.classes/flow-producer.ts - FlowProducer: creates parent-child job trees atomically.classes/queue-events.ts - QueueEvents: subscribes to Redis streams for real-time job events.classes/queue-getters.ts - QueueGetters: read-side helpers (counts, job lists, metrics).classes/redis-connection.ts - RedisConnection: manages ioredis lifecycle, reconnection, and script loading.classes/scripts.ts - Scripts: wrappers around all Lua command calls.classes/backoffs.ts - Built-in backoff strategies (fixed, exponential, custom).classes/child-pool.ts / classes/child-processor.ts - Sandboxed worker subprocess management.classes/errors/ - Typed error classes for specific failure modes.commands/ - ScriptLoader that reads .lua files and loads them into Redis as commands.enums/ - Shared numeric/string enums for commands, error codes, and metrics.interfaces/ - All TypeScript option and data interfaces (e.g. QueueOptions, WorkerOptions, JobsOptions).types/ - Type aliases including Processor<DataType, ReturnType>.utils/ - Low-level helpers re-exported for advanced users.maxRetriesPerRequest not set to null: ioredis will throw on blocking commands; always pass maxRetriesPerRequest: null in the connection options used by Worker.await worker.close() (not process.exit()) to drain in-flight jobs gracefully; use close(true) only for forced shutdown.RedisConnection instance or the singleton scriptLoader from commands/; instantiating multiple connections per process wastes memory and causes script re-upload on every reload.import IORedis: use import IORedis from 'ioredis' (default import) with "esModuleInterop": true in tsconfig.json; named imports will fail.Worker, resolve it with path.resolve(__dirname, './processor.js') or the worker will silently fail to spawn.I have the BullMQ source (bullmq@5.75.0) available at `source/` and the
integration guide at `USAGE.md`. Using only the real exports documented in
USAGE.md and visible in source/index.ts, source/classes/index.ts, and the
related interface/type files, please help me integrate BullMQ into my
existing Node.js/TypeScript project step by step.
My project uses:
- Node.js (version: ?)
- TypeScript (version: ?)
- Express / Fastify / NestJS (pick one)
- Redis at <host>:<port>
Tasks I need:
1. Set up a Queue named "<queue-name>" with my Redis connection.
2. Add a Worker that processes jobs of type <describe job shape>.
3. Add error handling using the typed errors from source/classes/errors/.
4. (Optional) Set up a repeatable job using Queue.upsertJobScheduler.
5. (Optional) Set up a FlowProducer for parent-child job dependencies.
Please show complete, runnable TypeScript code, import only from 'bullmq'
(mapping to source/), and follow the patterns in USAGE.md.
BullMQ is released under the MIT License. See the source/ directory for LICENSE if present, or refer to the upstream repository. Upstream package: bullmq on npm maintained by Taskforce.sh. Source repository: taskforcesh/bullmq on GitHub.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
SaaS, AI & Subscription Products
Free