A distributed job queue that actually works. RRQ is Rust-first: the orchestrator, protocol, and core producer/runner crates are implemented in Rust, with Python and TypeScript bindings for application integration.
Most job queues make you choose: either fight with complex distributed systems concepts, or accept unreliable "good enough" solutions. RRQ takes a different approach:
-
Rust orchestrator, any-language workers - The hard parts (scheduling, retries, locking, timeouts) are handled by a single-binary Rust orchestrator. Your job handlers are just normal async functions in your preferred language.
-
Redis as the source of truth - No separate databases to manage. Jobs, queues, locks, and results all live in Redis with atomic operations and predictable semantics.
-
Production-grade features built in - Retry policies, dead letter queues, job timeouts, cron scheduling, distributed tracing, and health checks work out of the box.
-
Fast and lightweight - The Rust orchestrator handles thousands of jobs per second with minimal memory. Workers are isolated processes that can be scaled independently.
┌──────────────────────────────┐
│ Your Application │
│ (Python, TypeScript, Rust) │
│ │
│ client.enqueue("job", {...}) │
└───────────────┬──────────────┘
│ enqueue jobs
▼
┌───────────────────────┐
│ Redis │
│ queues, jobs, locks │
└──────────┬────────────┘
│ poll/dispatch
▼
┌──────────────────────────────┐
│ RRQ Orchestrator │
│ (single Rust binary) │
│ • scheduling & retries │
│ • timeouts & deadlines │
│ • dead letter queue │
│ • cron jobs │
└──────────┬───────────────────┘
│ socket protocol
▼
┌─────────────────────────────────────────┐
│ Job Runners │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Python │ │ TypeScript │ │
│ │ Worker │ │ Worker │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────┘
| Package | Language | Purpose | Install |
|---|---|---|---|
| rrq (crates.io) | Rust | Orchestrator CLI (core) | cargo install rrq |
| rrq-producer | Rust | Native producer library | rrq-producer = "0.9" |
| rrq-runner | Rust | Native runner runtime | rrq-runner = "0.9" |
| rrq (PyPI) | Python | Producer + runner binding | pip install rrq |
| rrq-ts | TypeScript | Producer + runner binding | npm install rrq-ts |
cargo install rrqrrq --helpThis binding runs on top of the Rust rrq orchestrator.
pip install rrq[rrq]
redis_dsn = "redis://localhost:6379/0"
default_runner_name = "python"
[rrq.runners.python]
type = "socket"
cmd = ["rrq-runner", "--settings", "myapp.runner:settings"]
tcp_port = 9000# myapp/handlers.py
async def send_email(request):
email = request.params.get("email")
await do_send_email(email)
return {"sent": True}# myapp/runner.py
from rrq.registry import Registry
from rrq.runner_settings import PythonRunnerSettings
from myapp import handlers
registry = Registry()
registry.register("send_email", handlers.send_email)
settings = PythonRunnerSettings(registry=registry)rrq worker run --config rrq.tomlfrom rrq.client import RRQClient
client = RRQClient(config_path="rrq.toml")
job_id = await client.enqueue("send_email", {"params": {"email": "user@example.com"}})This binding runs on top of the Rust rrq orchestrator.
import { RRQClient, RunnerRuntime, Registry } from "rrq-ts";
// Enqueue jobs
const client = new RRQClient({ config: { redisDsn: "redis://localhost:6379/0" } });
await client.enqueue("send_email", { params: { email: "user@example.com" } });
// Run handlers
const registry = new Registry();
registry.register("send_email", async (request) => ({
job_id: request.job_id,
request_id: request.request_id,
status: "success",
result: { sent: true },
}));
const runtime = new RunnerRuntime(registry);
// RRQ launches runners with: --tcp-socket host:port
await runtime.runFromArgs();- Scheduled jobs - Defer execution by seconds or until a specific time
- Unique jobs - Idempotency with unique keys
- Rate limiting - Throttle job execution per key
- Debouncing - Deduplicate rapid submissions
- Cron scheduling - Recurring jobs with cron syntax
- Dead letter queue - Failed jobs are preserved for debugging
- Distributed tracing - OpenTelemetry context propagation
- Watch mode - Auto-restart runners on code changes
rrq/
├── docs/ # Documentation
├── examples/ # Usage examples
├── rrq-rs/ # Rust workspace (orchestrator, producer, runner, protocol)
├── rrq-py/ # Python binding package
└── rrq-ts/ # TypeScript package
- Redis 5.0+
- Rust toolchain (for RRQ core/orchestrator)
- Python 3.11+ (for Python SDK)
- Node.js 20+ or Bun (for TypeScript SDK)
Apache-2.0