Skip to main content

The most reliable backend for Django's task framework.

Project description

Threadmill

Threadmill: A queue agnostic worker for Django's task framework.
Documentation | Issues | Changelog | Funding 💚

A queue agnostic worker for Django's task framework.

Design Principles

  • Durability – We recover from any failures, even poorly written tasks.
  • Consistency – We never lose data, even if someone unplugs the power or network.
  • Utilization – We keep the CPU saturated with tasks, not with idle time or waiting for locks.

[!WARNING] Threadmill requires a development version of Django and is in a preview stage.

PyPi Version Test Coverage GitHub License

Sponsors

Sponsors

Setup

You need to have Django's Task framework set up properly.

uv add threadmill[redis]

Add threadmill to your INSTALLED_APPS in settings.py and configure the task backend:

# settings.py
import os

INSTALLED_APPS = [
    "threadmill",
    # ...
]

TASKS = {
    "default": {
        "BACKEND": "threadmill.backends.redis.RedisTaskBackend",
        "REDIS_URL": os.getenv("REDIS_URL", "redis://localhost:6379/0"),
    },
    # ...
}

Finally, you launch the worker pool:

uv run manage.py threadmill

Usage

Workers

The workers are inspired by Gunicorn, and the CLI is very similar.

Utilization

Depending on your workload, you can tweak the number of processes and threads. Processes allow for parallel compute (no GIL) while threads are great for low-memory concurrent IO.

uv run manage.py threadmill --processes 4 --threads 2

Health

If your tasks leak memory, you can recycle (restart) the workers after a certain number of tasks have been processed:

uv run manage.py threadmill --max-tasks 1000 --max-tasks-jitter 100

This will restart the workers after 1000 tasks have been processed, with a random jitter of up to 100 tasks to avoid all workers restarting at the same time.

Should a worker crash or be killed, the pool will automatically restart it.

Shutdown

A graceful shutdown is possible with the SIGTERM or a keyboard interrupt. All workers will finish the tasks they acquired and acknowledge them.

You can use --exit-empty to exit immediately after all tasks have been processed, which might be useful for draining a one-off queue.

Redis Backend Options

The RedisTaskBackend accepts the following options under OPTIONS in your TASKS configuration:

Option Default Description
lease_ttl timedelta(hours=1) Max processing time before a started task is marked FAILED.
result_ttl timedelta(days=1) How long task results are retained before automatic removal.
broker_interval timedelta(seconds=1) Interval between background broker maintenance passes.
batch_size 100 Max tasks to move or requeue per broker pass.

A task that is started but never acknowledged (lease expired) is marked FAILED with an AcknowledgementTimeout error. Set lease_ttl comfortably above your worst-case task runtime.

All keys for one backend alias share a Redis Cluster hash tag ({alias}), so every multi-key operation — including the cross-queue acquire — runs on a single shard. Scale horizontally by running additional backend aliases, not by relying on cross-slot operations.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

threadmill-0.2.0.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

threadmill-0.2.0-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file threadmill-0.2.0.tar.gz.

File metadata

  • Download URL: threadmill-0.2.0.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for threadmill-0.2.0.tar.gz
Algorithm Hash digest
SHA256 721b8ec14251479f0165b01088e105ebcbd5ab869e6f67b61637bbbf2143bbbe
MD5 ab43195e717d2cdf1f769f7a6d99fd33
BLAKE2b-256 1b2bf8e3bd3bcbdb6f0ff5bdc3b21e801b8b5bc8308ce656ebac11f54254fe54

See more details on using hashes here.

Provenance

The following attestation bundles were made for threadmill-0.2.0.tar.gz:

Publisher: release.yml on codingjoe/threadmill

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file threadmill-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: threadmill-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for threadmill-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 650e4f71aa2b4d76995cd944345574e1690d18f730bae8cb4919c6f8ede60772
MD5 aab2d213d043fc015df1251621fcf270
BLAKE2b-256 9ec43b0f0ffe5d2884a8359627aa467efe346f75c68f86ed0a2395180b1c7c3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for threadmill-0.2.0-py3-none-any.whl:

Publisher: release.yml on codingjoe/threadmill

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page