Background jobs for Rust

A Rust port of BullMQ. It uses the same Lua scripts and Redis data structures as the Node.js and Elixir libraries, so they can all work on the same queues.

cargo add bullmq

Rust 1.85+ (edition 2021) · tokio · Redis 6.2+ (or Valkey/Dragonfly)

Your first queue and worker

my_queue.rs
use bullmq::{Queue, QueueOptions, JobOptions};

let queue = Queue::new("Paint", QueueOptions::default()).await?;
queue
.add(
"cars",
serde_json::json!({"color": "blue"}),
Some(JobOptions {
delay: Some(30_000),
..Default::default()
}),
)
.await?;
my_worker.rs
use bullmq::{Worker, WorkerOptions, Job};
use std::sync::Arc;

let worker = Worker::new(
"Paint",
Arc::new(|job: Job, _token| {
Box::pin(async move {
if job.name() == "cars" {
paint_car(job.data()["color"].as_str().unwrap()).await;
}
Ok(serde_json::json!({"painted": true}))
})
}),
WorkerOptions {
concurrency: 100,
..Default::default()
},
)
.await?;

The same job handling as the Node.js library

All BullMQ libraries run the same Lua scripts on Redis and the same SQL on PostgreSQL, so jobs are handled the same way in every language. Only the API around those scripts differs from one library to the next.

More Rust examples

Common BullMQ features, written in Rust.

Global events

events.rs
use bullmq::{QueueEvent, QueueEvents, QueueEventsOptions};

let events = QueueEvents::new(
"Paint",
QueueEventsOptions::default(),
)
.await?;

while let Some(entry) = events.next_event().await {
match entry.event {
QueueEvent::Completed { job_id, .. } => {
println!("Job {job_id} completed");
}
QueueEvent::Failed { job_id, failed_reason, .. } => {
println!("Job {job_id} failed: {failed_reason}");
}
_ => {}
}
}

Repeatable jobs

repeatable.rs
use bullmq::job_scheduler::RepeatOptions;
use bullmq::{Queue, QueueOptions};

let queue = Queue::new("Paint", QueueOptions::default()).await?;

// Repeat job once every day at 3:15 (am)
queue
.upsert_job_scheduler(
"daily-submarine",
RepeatOptions {
pattern: Some("0 15 3 * * *".into()),
..Default::default()
},
Some("submarine"),
Some(serde_json::json!({"color": "yellow"})),
None,
)
.await?;

Rate limiting

ratelimit.rs
use bullmq::{Job, RateLimiterOptions, Worker, WorkerOptions};
use std::sync::Arc;

let worker = Worker::new(
"Paint",
Arc::new(|job: Job, _token| {
Box::pin(async move {
paint_car(&job).await;
Ok(serde_json::Value::Null)
})
}),
WorkerOptions {
limiter: Some(RateLimiterOptions {
max: 10,
duration: 1000,
}),
..Default::default()
},
)
.await?;

Retries & backoff

retry.rs
use bullmq::{Queue, QueueOptions, JobOptions};
use bullmq::types::BackoffStrategy;

let queue = Queue::new("Paint", QueueOptions::default()).await?;

queue
.add(
"car",
serde_json::json!({"color": "pink"}),
Some(JobOptions {
attempts: Some(3),
backoff: Some(BackoffStrategy::Exponential(1000)),
..Default::default()
}),
)
.await?;

Flows

flow.rs
use bullmq::{FlowJob, FlowProducer, FlowProducerOptions};

let flow = FlowProducer::new(FlowProducerOptions::default()).await?;

flow.add(FlowJob {
name: "Renovate".into(),
queue_name: "cars".into(),
data: serde_json::json!({}),
opts: None,
prefix: None,
children: Some(
["paint", "engine", "wheels"]
.into_iter()
.map(|name| FlowJob {
name: name.into(),
queue_name: "steps".into(),
data: serde_json::json!({}),
opts: None,
prefix: None,
children: None,
})
.collect(),
),
})
.await?;

Using BullMQ with Rust

Built on tokio

Workers are async and support configurable concurrency, stalled job detection and lock renewal.

Metrics

Collect time-series metrics for your queues and export them in Prometheus format.

Bindings

The API is trait-based and designed to make bindings to Go, C#, Python and other languages easy to write.

Node.js Rust

One queue, any language

Keep adding jobs from your Node.js services and process the CPU-heavy ones in Rust workers. The queue does not change.

What's available in Rust

  • Add jobs to queues Supported
  • Process jobs (workers) Supported
  • Delayed jobs Supported
  • Repeatable / scheduled jobs Supported
  • Job priorities Supported
  • Rate limiting Supported
  • Retries & backoff Supported
  • Flows (parent / child) Supported
  • Job events Supported
  • Redis backend Supported
  • PostgreSQL backend Coming soon
  • BullMQ Pro Coming soon

BullMQ Pro for Rust Coming soon

BullMQ Pro adds groups, observables and batches to the open source library. It is available for Node.js and Bun today, and support for Rust is on the way.

Groups
Observables
Batches

Get started with BullMQ for Rust