django-ox 1.9.0 What's new

Django tasks in your database

Stop running Redis to send an email. Queue work in your existing database, where a dead worker doesn't mean lost tasks.

Open source BSD 3-Clause pip install django-ox

orders/tasks.py Python
with transaction.atomic():
    order = Order.objects.create(...)
    send_confirmation.enqueue(order.pk)

2,000 of 2,000

Tasks finished after 20 worker kills per trial

up to 20% faster

Queue drain than django-tasks-db

0.71 s

To enqueue 10,000 tasks

New in django-ox 1.9.0

Everything is free and open source.

Unique tasks, batches, rate limiting and workflows are now included in django-ox under BSD 3-Clause. These four features require Django 6.0+.

A stable core public API since 1.0.0.

19 releases. Core public API stable since 1.0.0 (September 2026). The workflow API is provisional.

6,899 test cases in the 1.9.0 suite.

22 merged pull requests from 13 outside contributors.

Featured in PyCoder's Weekly #752 (). Listed in awesome-django under Task Queues.

Run fewer services

Keep the queue in your database

Tasks are rows you can inspect in Django admin. Run a dedicated worker without adding Redis or RabbitMQ.

Recover a stopped worker's tasks

Unfinished tasks return to the queue when a worker dies. You don't need a separate recovery script.

Commit tasks with your data

Create an order and enqueue its confirmation inside transaction.atomic(). A rollback leaves neither row behind.

Compare the workers

Up to 20% faster queue drain than django-tasks-db

Tasks per second. Higher is better.

2,000 tasks, 1 worker

django-ox: 118.5 tasks per second
django-tasks-db: 103.9 tasks per second

2,000 tasks, 4 workers

django-ox: 426.3 tasks per second
django-tasks-db: 387.1 tasks per second

20,000 tasks, 1 worker

django-ox: 115.2 tasks per second
django-tasks-db: 97.4 tasks per second

20,000 tasks, 4 workers

django-ox: 461.8 tasks per second
django-tasks-db: 401.6 tasks per second

All bars use a 0–500 tasks/s scale.

Benchmark: django-ox 1.3.0 vs django-tasks-db 0.13.0 on PostgreSQL 16, five runs per cell.

Methodology and results

django-ox

One project. All features included.

Free and open source under BSD 3-Clause.

Run tasks in your database

  • Database-backed Django Tasks worker
  • Retries and dead-worker recovery
  • Recurring schedules
  • Django admin integration
  • Health checks and bulk enqueue
What is django-ox?

A database-backed worker for Django's Tasks framework. Tasks live in database rows. django-ox includes retries, worker recovery, recurring schedules, unique tasks, batches, rate limiting and workflows.

Do I need Redis or RabbitMQ?

No. django-ox uses your existing database. You still run a worker process to execute tasks.

What happens if a worker stops mid-task?

Its unfinished task returns to the queue and may run again. Make tasks tolerate repeated execution. External side effects aren't exactly-once.

Can I enqueue a task inside a database transaction?

Yes. Put the database write and enqueue() inside the same transaction.atomic() block. Both rows must use the same database. They commit or roll back together.

Are all features included?

Yes. All features are free and open source under BSD 3-Clause. Unique tasks, batches, rate limiting and workflows are included in django-ox 1.9.0. These four features require Django 6.0+. See the feature overview.

What should I install?

For a new installation, run pip install django-ox. Follow the getting started guide to configure Django and run a worker.

The oxpull 1.9.0 package on PyPI is a metapackage. It depends on django-ox>=1.9.0 and contains no Python module. django-ox supplies the oxpull module.

How do I upgrade an earlier oxpull install?

Follow the tested upgrade procedure. Stop workers and back up the database first. Uninstall the earlier oxpull distribution before installing django-ox 1.9.0.

Do not uninstall an earlier oxpull distribution after installing django-ox 1.9.0 unless you then repair the shared files as described below. This warning does not apply to the oxpull 1.9.0 metapackage: uninstalling it leaves django-ox's files in place.

If you already ran pip install -U oxpull, or installed django-ox over an earlier oxpull distribution, keep workers stopped while repairing the overlapping install. Run pip uninstall oxpull, then pip install --force-reinstall --no-deps django-ox, then pip check. Resolve any errors reported by pip check, then restart workers.