Registry / workflow / bullmq

bullmq

JSON →
library3.1.0pypypi✓ verified 27d ago

BullMQ for Python is an official Python port of the popular Node.js message queue, designed for reliable background job processing using Redis. It leverages `asyncio` for efficient, concurrent task execution and is interoperable with its Node.js counterpart due to shared Lua scripts. Currently at version 2.20.3, the library sees active development with frequent bug fixes and feature enhancements, including new major versions that may introduce breaking changes.

pip install bullmq
INSTALL
IMPORT
SIG · BULLMQ
B
bullmq
workflowpythonv3.1.0
Install
3.1s avg
Import
555ms
Disk
30MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v3.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.460s · 33.5MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 3.1s · import 0.428s · 34MB
30MB installed
● package 30MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Queue
✓ from bullmq import Queue
Worker
✓ from bullmq import Worker
QueueEvents
✓ from bullmq import QueueEvents
FlowProducer
✓ from bullmq import FlowProducer

This quickstart demonstrates how to add jobs to a BullMQ queue and process them with a worker. It uses `asyncio` for asynchronous operations. Ensure a Redis server is running (e.g., via `docker run -d -p 6379:6379 redis:latest`) and configure the `REDIS_URL` environment variable or provide explicit connection details. In a production environment, the queue producer and worker would typically run in separate processes or services.

import asyncio import os from bullmq import Queue, Worker REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379') async def add_job_to_queue(): # Connect to Redis. Pass 'connection' as a dictionary in options. queue = Queue("myQueue", connection={"host": "localhost", "port": 6379}) print(f"Adding job to queue 'myQueue' on {REDIS_URL}") job = await queue.add("myJobName", {"foo": "bar"}) print(f"Job added with ID: {job.id}, Data: {job.data}") await queue.close() async def process_job(job, job_token): print(f"Processing job {job.id} with data: {job.data}") # Simulate async work await asyncio.sleep(1) return {"status": "completed", "original_data": job.data} async def start_worker(): print(f"Starting worker for queue 'myQueue' on {REDIS_URL}") # Connect to Redis. Pass 'connection' as a dictionary in options. worker = Worker("myQueue", process_job, connection={"host": "localhost", "port": 6379}) # You can listen for worker events (optional) worker.on("completed", lambda job, result: print(f"Job {job.id} completed with result: {result}")) worker.on("failed", lambda job, err: print(f"Job {job.id} failed with error: {err}")) print("Worker started. Press Ctrl+C to stop.") # Keep the worker running (e.g., for a long time in a real application) try: while True: # Keep worker alive for demonstration await asyncio.sleep(3600) # Sleep for a long time except asyncio.CancelledError: pass finally: print("Shutting down worker...") await worker.close() async def main(): # This example assumes a Redis server is running at localhost:6379 # For real applications, use environment variables for connection details. # docker run -d -p 6379:6379 redis:latest # Run adding a job and starting a worker concurrently # For a real application, these would typically run in separate processes/services. await asyncio.gather(add_job_to_queue(), start_worker()) if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: print("Application stopped by user.")
Debug
Known issues
breakingBullMQ v2.0.0 introduced breaking changes. Specifically, Redis connection parameters must now be provided as part of the `options` dictionary for `Queue` and `Worker` constructors (e.g., `connection={'host': 'localhost', 'port': 6379}`). Additionally, worker markers now use a dedicated key in Redis instead of a special job ID, which impacts internal state management.
fix
Update `Queue` and `Worker` instantiation to pass connection details within the `connection` key of the options dictionary. Review application logic if directly interacting with internal Redis keys related to worker markers.
affects: >=2.0.0
gotchaWorkers may encounter 'Missing lock for job X.moveToFinished' errors. This usually means a job lost its lock during processing. Common causes include high CPU usage on the worker preventing lock renewal, loss of communication with Redis, or the job being forcefully removed.
fix
Reduce worker concurrency, optimize job processing code, ensure stable network connectivity to Redis, consider increasing `lockDuration` in worker options, and implement proper job state checks before attempting to remove jobs. Ensure Redis `maxmemory-policy` is set to `noeviction`.
affects: All
gotchaThe `process` function for a BullMQ `Worker` is expected to have two positional arguments: `job` and `job_token`, even if `job_token` is not explicitly used for manual job manipulation. Omitting `job_token` will cause a `TypeError`.
fix
Always define your worker's `process` function with `async def process(job, job_token): ...`.
affects: All (especially in v2.x documentation examples)
gotchaRedis-py (the underlying client for BullMQ Python) returns binary responses by default. If you are using a custom Redis client configuration and expect string responses, you must pass `decode_responses=True` to the Redis client constructor.
fix
When creating a custom Redis connection object for BullMQ, ensure `decode_responses=True` is set if you need decoded string responses.
affects: All
gotchaPassing undefined, empty, or non-string values (e.g., objects or arrays) when using environment variables or other dynamic inputs with BullMQ methods can lead to `ERR Error running script ... Lua redis() command arguments must be strings or integers` errors.
fix
Always validate and sanitize input, especially for connection parameters, queue names, and job data. Ensure all values passed to BullMQ or its underlying Redis commands are strings or integers. Use `os.environ.get('KEY', '')` or raise errors if critical environment variables are missing.
affects: All
gotchaFor robust error handling and retries, your worker's processor function should always raise Python `Exception` objects (or subclasses thereof) when a job fails. BullMQ relies on catching these exceptions to mark jobs as failed and apply retry logic based on `attempts` and `backoff` options.
fix
Ensure that any failure condition within your `process` function explicitly raises an `Exception` (e.g., `raise ValueError('Invalid data')`). Configure `attempts` and `backoff` options when adding jobs to the queue for automatic retries.
affects: All
Errors
Common errors & fixes
Missing lock for job 1234. moveToFinished
This error occurs when a job being processed by a worker unexpectedly loses its 'lock' in Redis, often due to high CPU usage preventing lock renewal, an unstable Redis connection, or an incorrect Redis maxmemory-policy that evicts BullMQ keys.
fix
Optimize your job processing code to reduce CPU load, reduce worker concurrency, ensure stable network connectivity between the worker and Redis, configure your Redis server with `maxmemory-policy noeviction`, and consider increasing the `lockDuration` in the Worker options if jobs are inherently long-running.
ModuleNotFoundError: No module named 'redis'
The official BullMQ Python library depends on the `redis` Python client, which is not automatically installed by default if you install `bullmq` directly in some environments, or if it's missing from your project's dependencies.
fix
Install the `redis` Python client library using pip: `pip install redis`.
Worker is ready and listening for jobs. (but jobs are not processed)
The BullMQ worker appears to be initialized correctly and logs that it's ready, but it does not pick up and process jobs from the queue. This can happen due to an incorrect queue name, a worker not properly connected to Redis, the main application exiting prematurely, or the processor function hanging indefinitely.
fix
Ensure the queue name configured for the worker exactly matches the queue name used by the job producer. Verify that the Redis connection details are correct and accessible. Ensure your Python application keeps the `asyncio` event loop running for the worker, typically by using `await worker.run()` or `await asyncio.Future()` in your main worker loop. Also, ensure your processor function either completes or explicitly raises exceptions if it encounters an issue.
Connection refused
The BullMQ client (either Queue or Worker) cannot establish a connection to the Redis server because Redis is not running, is running on a different host/port than configured, or a firewall is blocking the connection.
fix
Verify that your Redis server is running and accessible (e.g., by running `redis-cli ping` from your terminal, which should return `PONG`). Double-check the host, port, and any authentication credentials in your BullMQ connection configuration. Ensure no firewalls are blocking the Redis default port (6379) or your configured port.
TypeError: process() takes 1 positional argument but 2 were given
This error occurs when the processor function provided to the BullMQ `Worker` is defined to accept only one argument (the `job`), but BullMQ expects it to accept two arguments (`job` and `token`) by default for manual job processing or specific API interactions.
fix
Adjust the signature of your worker's processor function to accept both the `job` and `token` arguments. For example: `async def process(job, token):` or `async def process(job: Job, token: Optional[str] = None):`.
Upgrade
Version history
3.1.0latest on PyPI · released Aug 28, 2026
Audit
Dependencies
redisrequiredPython Redis client for communication with the Redis server.
msgpackrequiredMessagePack serialization for efficient data handling.
semverrequiredSemantic versioning utilities.
RedisrequiredExternal dependency: a running Redis 5.0+ server (6.2+ recommended) is required for BullMQ to function.
Agent activity
40 hits · last 30 days
node
36
OpenAI (training)
1
Resources
bullmq — pip install bullmq · libregistry