( Background work )

Background jobs and cron for Python backends

austial.jobs runs work outside the request path. It provides a JobQueue, a Worker loop with retries and exponential backoff, scheduled jobs with @Cron, and enqueueable jobs with @Job, all declared on ordinary injectable classes.

Declaring jobs and schedules

Put handlers on an @Injectable class. Raise on failure and the worker retries the job. Cron expressions and shorthand such as @daily are supported, with optional jitter.

from austial import Injectable
from austial.jobs import Cron, Job


@Injectable()
class Payments:
    @Job("send-remittance", max_attempts=5, backoff_seconds=60)
    async def send(self, *, remittance_id: str) -> None:
        # Raise on failure and the worker retries.
        ...

    @Cron("@daily")
    async def daily_reconciliation(self) -> None:
        ...

Sensible defaults

JobsConfig defaults to a concurrency of 4, three attempts per job, a 30 second base backoff and a one second poll interval. Override them per environment. JobsModule is global, so JobQueue, JobRegistry and Worker can be injected anywhere.

Pluggable backends

An in-memory backend ships as the default, which suits tests and single-node deployments. Redis, Arq and Dramatiq wiring is deferred, and you can supply your own JobBackend. A jobs-scoped idempotency store lets you deduplicate enqueue calls.

Frequently asked questions

How is this different from FastAPI's BackgroundTasks?

BackgroundTasks run after a response in the same process. austial.jobs adds a queue, workers, retries with backoff, scheduled jobs and job status, and the backend is pluggable.

Can I run it across several servers?

The default backend is in-memory and process-local. For several workers you would supply your own JobBackend, because Redis-based wiring is not shipped yet.

How do retries work?

The worker retries a failing job up to its max_attempts, waiting with exponential backoff that starts from backoff_seconds.

Go deeper in the docs

( Keep reading )

( Click. Copy. Build. )

Seeing “command not found”? Run uv tool update-shell, then open a new terminal. Details