Run work off-request with a background job
Problem
Sending email (or any slow task) inside a request handler blocks the response.
Implement the Job trait and enqueue it; a worker pool runs it off-request with automatic exponential-backoff retry.
#[async_trait::async_trait]
impl Job for SendWelcome {
async fn run(&self, ctx: &JobContext) -> Result<(), JobError> {
ctx.mailer().send(welcome_email(self.user_id)).await?;
Ok(())
}
}
// In the handler — returns immediately:
queue.enqueue(SendWelcome { user_id }).await?;
Durable queue
The default queue is in-memory; enable jobs-postgres for a DB-backed queue (FOR UPDATE SKIP LOCKED) that survives restarts and scales across workers.