Included in every project
Generated projects ship with a background job queue stored in the project's
own Postgres database. There is no option to select at generation time and
nothing to install: no Redis, no Postgres extension, no extra service. The
queue is part of the shared shiprust-core crate, the jobs table comes
from the project's migrations, and the worker starts inside the web process
by default.
Jobs are rows with a payload and a handler. Enqueue one from a request, inside the same transaction as the data it belongs to, and the worker runs it later, retrying with backoff if it fails. Queued jobs survive crashes, restarts and deploys.
What you get
- A
Jobtrait: a serde struct with a stableKIND,MAX_ATTEMPTS,TIMEOUTand an asyncrunhandler that receives your app state. enqueue(&mut *tx, &job, options)with optionalrun_atdelay anddedupe_key, usable with a pool, connection or transaction.- A worker with
FOR UPDATE SKIP LOCKEDclaims, 60-second leases kept alive by heartbeats, exponential backoff, dead-letter rows, graceful shutdown that drains running jobs, and retention of finished rows. cargo run -- jobs statsandcargo run -- jobs retry <id>.JOBS_WORKER=true|false|onlyand aworkercommand, so the same image runs jobs in the web container or in a separate one.- An example job, a welcome email after signup verification, with an end-to-end test that runs the worker against a local mail double.
Handlers run at least once; the project guide explains how to keep them idempotent and when to use a job instead of the request handler, the bounded CPU helper or a Tokio interval.
Where to read more
The generated project's guide at app/content/docs/background-jobs.md
(also served at /docs/background-jobs in your running app) covers defining
jobs, enqueueing, guarantees, running the worker and operating the queue.
The CapRover and Docker guides in your
project describe the optional separate worker container.
This site runs on the same queue: the purchase confirmation email after a lifetime purchase is a background job. The queue supports both in-process and dedicated workers.
Read how we implement Rust background jobs with a Postgres queue for a code-level walkthrough of transactional enqueueing, leases, retries, and at-least-once delivery.