{
  "id": "job-queue",
  "title": "Redis job queue",
  "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/",
  "summary": "Run a reliable background job queue with Redis.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc"
  ],
  "last_updated": "2026-05-14T08:58:05-05:00",
  "children": [
    {
      "id": "redis-py",
      "summary": "Implement a Redis job queue in Python with redis-py",
      "title": "Redis job queue with redis-py",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/redis-py/"
    },
    {
      "id": "nodejs",
      "summary": "Implement a Redis job queue in Node.js with node-redis",
      "title": "Redis job queue with node-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/nodejs/"
    },
    {
      "id": "go",
      "summary": "Implement a Redis job queue in Go with go-redis",
      "title": "Redis job queue with go-redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/go/"
    },
    {
      "id": "java-jedis",
      "summary": "Implement a Redis job queue in Java with Jedis",
      "title": "Redis job queue with Jedis",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/java-jedis/"
    },
    {
      "id": "java-lettuce",
      "summary": "Implement a Redis job queue in Java with Lettuce",
      "title": "Redis job queue with Lettuce",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/java-lettuce/"
    },
    {
      "id": "dotnet",
      "summary": "Implement a Redis job queue in C# with StackExchange.Redis",
      "title": "Redis job queue with StackExchange.Redis",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/dotnet/"
    },
    {
      "id": "php",
      "summary": "Implement a Redis job queue in PHP with Predis",
      "title": "Redis job queue with Predis",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/php/"
    },
    {
      "id": "ruby",
      "summary": "Implement a Redis job queue in Ruby with redis-rb",
      "title": "Redis job queue with redis-rb",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/ruby/"
    },
    {
      "id": "rust",
      "summary": "Implement a Redis job queue in Rust with redis-rs",
      "title": "Redis job queue with redis-rs",
      "url": "https://redis.io/docs/latest/develop/use-cases/job-queue/rust/"
    }
  ],
  "page_type": "content",
  "content_hash": "962c107649f26a710d043b9adb4db6faf1bb2a9a48189462b32632c4c5e3222a",
  "sections": [
    {
      "id": "when-to-use-a-job-queue",
      "title": "When to use a job queue",
      "role": "overview",
      "text": "Use a Redis job queue when you need to offload background work — sending email, processing payments, image processing, ML inference, webhooks — from user-facing request paths and distribute it reliably across a pool of workers."
    },
    {
      "id": "why-the-problem-is-hard",
      "title": "Why the problem is hard",
      "role": "content",
      "text": "Synchronous processing of background work blocks user requests and degrades latency under load.\nA single user action often triggers multiple downstream tasks (send email, update analytics,\nnotify billing) and without a shared queue each service needs point-to-point integration that\nbecomes brittle at scale. Some of the obvious workarounds have real drawbacks:\n\n-   **Simple in-process queues** lose jobs on crash and can't distribute work across multiple\n    workers or services.\n-   **Polling a database for pending rows** generates constant load on the primary database and\n    introduces handoff races between workers competing for the same row.\n-   **Adding a dedicated message broker** (RabbitMQ, Kafka, SQS) means another piece of\n    infrastructure to deploy, monitor, and pay for — often just to move jobs a few hops.\n\nA workable job queue needs at-least-once delivery, an atomic handoff from queue to worker, and\na way to reclaim jobs from workers that crashed mid-processing. You also need to track per-job\nstatus, retry counts, and completion results without those records leaking forever."
    },
    {
      "id": "what-you-can-expect-from-a-redis-solution",
      "title": "What you can expect from a Redis solution",
      "role": "content",
      "text": "You can:\n\n-   Decouple APIs and services from workers so user-facing latency stays low under bursty load.\n-   Distribute jobs across many workers with at-least-once delivery and automatic retry of\n    failed or timed-out jobs.\n-   Run FIFO, LIFO, priority, and delayed-execution queues on core Redis data structures.\n-   Reclaim jobs from crashed workers using a visibility timeout, so no job is lost when a\n    worker dies mid-processing.\n-   Fan out a single user action to multiple downstream services through streams and consumer\n    groups.\n-   Use established libraries — Sidekiq, Celery, Bull/BullMQ, RQ — that implement reliable\n    queue patterns on Redis out of the box."
    },
    {
      "id": "how-redis-supports-the-solution",
      "title": "How Redis supports the solution",
      "role": "content",
      "text": "In practice, a Redis job queue stores pending job IDs in a list and moves each claimed job\natomically to a *processing* list so a crashed worker's job can be reclaimed later. Job\nmetadata (payload, status, attempts, result) lives in a hash, and completed jobs are cleaned\nup automatically with a TTL.\n\nRedis provides the following features that make it a good fit for background jobs:\n\n-   [`LPUSH`](https://redis.io/docs/latest/commands/lpush) and [`BRPOPLPUSH`](https://redis.io/docs/latest/commands/brpoplpush)\n    (or [`BLMOVE`](https://redis.io/docs/latest/commands/blmove)) for atomic enqueue and blocking claim,\n    so a worker dequeues a job and registers it in the processing list in a single round trip.\n-   [Lists](https://redis.io/docs/latest/develop/data-types/lists) for the *processing list* visibility-timeout\n    pattern — jobs move atomically from pending to processing, and a reclaimer scans for\n    timed-out jobs and moves them back.\n-   [Sorted sets](https://redis.io/docs/latest/develop/data-types/sorted-sets)\n    ([`ZADD`](https://redis.io/docs/latest/commands/zadd),\n    [`ZRANGEBYSCORE`](https://redis.io/docs/latest/commands/zrangebyscore)) for delayed execution and\n    priority queues, scored by run-at timestamp or priority.\n-   [Streams](https://redis.io/docs/latest/develop/data-types/streams) with\n    [consumer groups](https://redis.io/docs/latest/develop/data-types/streams#consumer-groups) for fan-out\n    across multiple worker pools with independent progress tracking.\n-   [Hashes](https://redis.io/docs/latest/develop/data-types/hashes) for job metadata with\n    [`EXPIRE`](https://redis.io/docs/latest/commands/expire) so completed jobs are cleaned up automatically.\n-   [Pub/Sub](https://redis.io/docs/latest/develop/pubsub)\n    ([`PUBLISH`](https://redis.io/docs/latest/commands/publish),\n    [`SUBSCRIBE`](https://redis.io/docs/latest/commands/subscribe)) for job completion signalling so the\n    submitter is notified without polling.\n-   Sub-millisecond latency on enqueue and dequeue, which keeps the producer side cheap."
    },
    {
      "id": "ecosystem",
      "title": "Ecosystem",
      "role": "content",
      "text": "The following libraries implement reliable job-queue patterns on Redis:\n\n-   **Python**: [Celery](https://docs.celeryq.dev/),\n    [RQ](https://python-rq.org/),\n    [Dramatiq](https://dramatiq.io/)\n-   **Ruby**: [Sidekiq](https://sidekiq.org/),\n    [Resque](https://github.com/resque/resque)\n-   **Node.js**: [Bull](https://github.com/OptimalBits/bull),\n    [BullMQ](https://docs.bullmq.io/)\n-   **Go**: [Asynq](https://github.com/hibiken/asynq)\n-   **Java**: [Redisson](https://redisson.org/),\n    [Spring Batch](https://spring.io/projects/spring-batch) (Redis job repository)\n-   **.NET**: [Hangfire](https://www.hangfire.io/) (Redis storage)"
    },
    {
      "id": "code-examples-to-build-your-own-redis-job-queue",
      "title": "Code examples to build your own Redis job queue",
      "role": "example",
      "text": "The following guides show how to build a simple Redis-backed job queue.\nEach guide includes a runnable interactive demo for each of the following client libraries:\n\n* [redis-py (Python)](https://redis.io/docs/latest/develop/use-cases/job-queue/redis-py)\n* [node-redis (Node.js)](https://redis.io/docs/latest/develop/use-cases/job-queue/nodejs)\n* [go-redis (Go)](https://redis.io/docs/latest/develop/use-cases/job-queue/go)\n* [Jedis (Java)](https://redis.io/docs/latest/develop/use-cases/job-queue/java-jedis)\n* [Lettuce (Java)](https://redis.io/docs/latest/develop/use-cases/job-queue/java-lettuce)\n* [StackExchange.Redis (C#)](https://redis.io/docs/latest/develop/use-cases/job-queue/dotnet)\n* [Predis (PHP)](https://redis.io/docs/latest/develop/use-cases/job-queue/php)\n* [redis-rb (Ruby)](https://redis.io/docs/latest/develop/use-cases/job-queue/ruby)\n* [redis-rs (Rust)](https://redis.io/docs/latest/develop/use-cases/job-queue/rust)"
    }
  ],
  "examples": []
}
