Documentation navigation

Background Jobs with Django Q2

Generated projects use Django Q2 for asynchronous work.

If you are still choosing a queue, read Django Background Tasks: Choose a Queue for a workload-based comparison of Django 6 Tasks, Django Q2, and Celery.

If the earlier decision is whether to keep work in the HTTP request, use Django Async Views vs Background Tasks to compare request lifetime, transaction timing, retries, and user-visible state.

Why Django Q2 is used

Django Q2 is simple to operate inside a Django-first stack and works well for tasks like:

  • project artifact generation,
  • analytics/event processing,
  • webhook side effects,
  • email and non-blocking integrations.

For a concrete queue boundary, the Django Stripe subscriptions guide keeps signature verification and entitlement updates near the webhook request while moving slow, repeatable side effects to Q2.

Current pattern in this codebase

Tasks are queued from request code using async_task, for example:

  • apps.core.views.create_project queues project generation
  • worker process runs python manage.py qcluster

Core queue settings are in djass/settings.py under Q_CLUSTER.

Running workers locally

Workers run as part of make serve (Docker Compose).

If needed, restart only workers:

make restart-worker

Adding a new background task

  1. Create a pure function in apps/core/tasks.py (or a focused task module).
  2. Keep inputs serializable (ids, strings, dicts).
  3. Queue with async_task("path.to.function", ...) from views/services.
  4. Log key context (entity id, action, error path). The production Django logging guide shows how to carry an explicit correlation id from the request into the worker without logging payloads or credentials.
  5. Record user-facing status when task state matters.

Reliability guidelines

  • Make tasks idempotent where possible.
  • Validate records exist before processing.
  • Store failure details on model fields when users need visibility.
  • Prefer retryable operations and defensive exception handling.
  • Monitor useful-work freshness through the queue rather than treating a green web process or Redis check as proof that workers are consuming jobs. The Django health check guide defines the separate readiness and heartbeat contracts.
  • For recurring work, define catch-up, intended-slot, overlap, idempotency, and completion policy with the Django scheduled-tasks guide before creating a Q2 schedule.

Debug checklist

If tasks are not processing:

  • confirm Redis is reachable,
  • check worker container/process logs,
  • verify task path string matches import path,
  • verify env/config parity between web and worker services.