For the complete documentation index, see llms.txt. This page is also available as Markdown.

Introduction

BullMQ is available as a native Rust crate with full async/await support.

Installation

Add BullMQ to your project via Cargo:

cargo add bullmq-rust

Or add it to your Cargo.toml:

[dependencies]
bullmq-rust = "0.1"

The crate is published as bullmq-rust (the bullmq name on crates.io is taken by an unrelated, abandoned crate), but it is imported in code as bullmq — e.g. use bullmq::{Queue, Worker};.

BullMQ for Rust requires:

  • Rust 1.85+

  • Tokio runtime

  • Redis 6.2+

Get Started

BullMQ uses Tokio for async processing. All operations are non-blocking and designed for high-throughput concurrent workloads.

Adding Jobs to a Queue

use bullmq::{Queue, QueueOptions};

#[tokio::main]
async fn main() -> bullmq::Result<()> {
    let queue = Queue::new("my-queue", QueueOptions::default()).await?;

    // Add a job with JSON data
    queue.add("my-job", serde_json::json!({
        "foo": "bar"
    }), None).await?;

    Ok(())
}

Processing Jobs with a Worker

Listening to Worker Events

Concurrency

Configure how many jobs are processed simultaneously:

The concurrency can be changed dynamically at runtime:

Progress Tracking

Report progress from inside the processor:

Job Retries with Backoff

Connection Configuration

Instead of a URL you can use typed connection fields. When host is set, the URL is built from these fields (use tls: true for a rediss:// TLS connection):

Key Differences from Node.js

Aspect
Node.js
Rust

Runtime

Event loop (single-threaded)

Tokio (multi-threaded async)

Processor

async function or sandboxed file

Arc<dyn Fn(Job, CancellationToken) -> Pin<Box<...>>>

Events

EventEmitter pattern

mpsc::UnboundedReceiver<WorkerEvent>

Error handling

Exceptions

Result<T, Error> types

Cancellation

AbortSignal

CancellationToken

Concurrency

Cooperative (single core)

True parallelism across all CPU cores

Compatibility

The Rust implementation uses the same Lua scripts and Redis data structures as the Node.js and Python versions. This means:

  • Jobs added by Node.js workers can be processed by Rust workers (and vice versa)

  • Queue state is fully shared across all language implementations

  • You can mix languages in a single deployment

Last updated

Was this helpful?