Delayed jobs
Job supports immediate execution and one future execution per enqueue request. Use delayed jobs for reminders, retry handoffs, provider syncs, delayed cleanup, trial lifecycle work, and other task execution that should happen after the current request.
Immediate execution
Section titled “Immediate execution”await jobs.enqueue("send-email", { to: "user@example.com", subject: "Welcome",})Delay by seconds
Section titled “Delay by seconds”Use delaySeconds when the task should run after a relative delay:
await jobs.enqueue("send-reminder", { userId: "user_123",}, { delaySeconds: 3600,})Run at a specific time
Section titled “Run at a specific time”Use runAt when you already have the execution timestamp:
await jobs.enqueue("trial-ending-email", { userId: "user_123",}, { runAt: "2026-06-01T09:00:00.000Z",})runAt accepts a Date or an ISO timestamp string.
Delays and retries
Section titled “Delays and retries”delaySeconds and runAt control the first delivery. Retry delays are
controlled by the task retry policy:
jobs.task("sync-provider", { retry: { attempts: 5, backoff: "exponential", initialDelaySeconds: 30, maxDelaySeconds: 900, },}, async (payload) => { await syncProvider(payload.accountId)})Check or cancel a delayed run
Section titled “Check or cancel a delayed run”enqueue returns a run ID. Store it when your app needs to show status or
cancel future work:
const run = await jobs.enqueue("send-reminder", { userId: "user_123",}, { delaySeconds: 3600,})
const latest = await jobs.runs.get(run.runId)
await jobs.runs.cancel(run.runId)Replay a delayed task payload
Section titled “Replay a delayed task payload”Replay creates a new run from a previous run payload:
await jobs.runs.replay("run_123", { reason: "customer requested another reminder",})