Skip to main content

Django Redis Tasks

Build Status Security Maintenance PyPI version PyPI downloads Python versions

This is a Redis-backed implementation of Django's django.tasks framework.

django-queues

Queue storage and worker execution are provided by django-queues, a generic Django queue package. django-redis-tasks is a thin translation layer on top of it: it maps Django's task vocabulary (Task, TaskResult, TaskResultStatus) onto django-queues' generic queue vocabulary (QueueEntry, QueueEntryStatus), and provides the handler function that executes queued task calls.

This package does not manage Redis connections, run a worker loop, or start anything during Django's application startup — django-queues owns all of that, including its manage.py runqueues management command.

Deferred tasks

run_after is supported. The backend normalizes the datetime to UTC at enqueue: that UTC instant is stored on the task payload and passed to django-queues as available_at. Reconstruction therefore does not depend on the reader's USE_TZ or TIME_ZONE. Redis TIME decides when the entry becomes claimable; workers do not record an attempt or emit started/finished signals while the task is only waiting.

  • Aware datetimes are converted to UTC.
  • Naive datetimes are accepted only when USE_TZ is False; they are interpreted in Django's current timezone, then converted to UTC. When USE_TZ is True, Django rejects a naive run_after at enqueue. Legacy naive payload values are still normalized to UTC on read.
  • A past or current run_after is eligible for dispatch immediately.
  • A worker that has no due work waits until a deferred task becomes due; it does not busy-poll the application clock.

Redis runtime

django-queues 1.2.0 requires Redis 7+ and a deployed Function library before the application or a worker starts:

python manage.py redis_lua_lib --deploy

Queue aliases must match [A-Za-z0-9_-]. Redis keys from django-queues before 1.2.0 are not compatible; start from empty queue keys or a new Redis logical database.

Installation

uv add django-redis-tasks

Configuration

django_queue must be added to INSTALLED_APPS. redis_tasks does not require app registration today, but adding it is recommended for forward compatibility with future Django integration points such as models, observer registrations, templates, and static assets:

INSTALLED_APPS = [
    ...
    "django_queue",
    "redis_tasks",
    ...
]

Configuration is two settings working together: QUEUES (owned by django-queues) configures the underlying Redis queue and registers this package's handler; TASKS (owned by Django) configures the task backend and points it at that queue.

QUEUES = {
    "default": {
        "BACKEND": "django_queue.backends.redis.RedisAsyncPriorityQueueJson",
        "LOCATION": "redis://localhost:6379/12",
        "HANDLER": "redis_tasks.handlers.handle_task_entry",
        "ENTRY_CLASS": "redis_tasks.entries.TaskQueueEntry",
        "WORKER": "redis_tasks.worker.RedisTaskWorker",
    },
}

TASKS = {
    "default": {
        "BACKEND": "redis_tasks.backend.RedisBackend",
        "OPTIONS": {
            "queue_alias": "default",  # the QUEUES alias to delegate to; defaults to this TASKS alias
        },
    },
}

A Django project may configure multiple QUEUES/TASKS alias pairs, each backed by its own Redis queue.

TaskQueueEntry records worker_ids as the ordered history of worker-process UUIDs that began dispatching a task; TaskResult.attempts is the length of that list. Redis automatically recovers an entry whose worker lease expires, so a task can execute more than once. Make handlers with side effects idempotent.

Running a worker

Task execution happens out-of-process, via django-queues' own management command:

python manage.py runqueues

This discovers every QUEUES alias with a HANDLER configured (including redis_tasks.handlers.handle_task_entry) and runs its worker until the process receives a termination signal. Queue connections are initialized lazily when their aliases are first used, but no task worker or handler execution starts in a Django web process — run runqueues as a separate, standalone service.

Async applications

django-redis-tasks supports Django's native asynchronous task API. In an ASGI view, consumer, or other coroutine, use await task.aenqueue(...) to write directly through django-queues' asynchronous Redis API. Refresh an existing result with await result.arefresh(). Neither operation needs this backend to cross Django's synchronous task-backend bridge, so queue I/O stays on the caller's event loop.

from django.http import JsonResponse


async def start_report(request):
    result = await build_report.aenqueue(request.user.pk)
    return JsonResponse({"task_id": result.id})


async def refresh_report(result):
    await result.arefresh()
    return result.status

Tasks declared with async def are also awaited directly by this package's handler inside django-queues' worker event loop. A synchronous task function is still safe, but Django runs it through a thread bridge to avoid blocking that loop.

Queue work is deliberately outside the ASGI request runtime. The separate runqueues service owns task dispatch and recovery, while django-queues' process-local queue runtime owns lifecycle-observer delivery. This lets an application use task status and best-effort queue observers without starting workers from views or competing with request handling for an event loop.

An entirely asynchronous application should also use async middleware, views, task functions, and task-signal receivers. Synchronous middleware, ORM work, task functions, and signal receivers remain supported, but Django adapts those specific boundaries through its thread bridge.

Usage

A task is created using Django's @task decorator:

from django.tasks import task


@task()
def calculate_meaning_of_life() -> int:
    return 42


@task()
async def nudge_nudge_wink_wink() -> list[str]:
    return ["say", "no", "more"]

Release files for django-redis-tasks 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-redis-tasks 1.0.0
File Size Uploaded
django_redis_tasks-1.0.0.tar.gz 15.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-redis-tasks 1.0.0
File Interpreter ABI Platform
django_redis_tasks-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.4 kB

Release files / django_redis_tasks-1.0.0.tar.gz

Download URL django_redis_tasks-1.0.0.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d5f88a286f30139ff145c2c31d1af4307443b424dbd4d5c683cf1c72a291158b
BLAKE2b-256 checksum
How to use checksums
25f9a7a8a00a01051a57dd4bff5fdc1bd6c987079b0f76d6a53f18d0f6b9fd52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / django_redis_tasks-1.0.0-py3-none-any.whl

Download URL django_redis_tasks-1.0.0-py3-none-any.whl
Size 10.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e472cccfd628401be261fc2e1fffa1f7846a426a372f42583251ba89dc2fdef
BLAKE2b-256 checksum
How to use checksums
bd4e61bee090ab0117a216635daa9af4aaed695dcf26c1008c1e4143abff763f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page