Skip to main content
Live. This area is documented as current, user-reliable behavior.

Goal

Move work out of request handlers while keeping retries and visibility.

Prerequisites

  • A StackShift client and handler route

Workflow

1
Create or choose a queue name.
2
Enqueue work with a job name and payload.
3
Register a matching handler.
4
Set retry and delay options per job when needed.

Enqueue jobs

await stackshift.queue('emails').enqueue(
  'sendReceipt',
  { orderId: 'order_123', customerId: 'cus_123' },
  {
    idempotencyKey: 'receipt:order_123',
    maxAttempts: 5,
  }
)

Handlers

stackshift.job<{ orderId: string; customerId: string }>('sendReceipt', async ({ payload, step }) => {
  const order = await step.run('load-order', () => loadOrder(payload.orderId))
  await step.run('send-receipt-email', () => sendReceiptEmail(order))

  return { sent: true }
})

Retries and delayed jobs

Retry later
await stackshift.queue('billing').enqueue(
  'syncInvoice',
  { invoiceId: 'in_123' },
  {
    maxAttempts: 8,
    scheduledAt: '2026-05-06T09:00:00.000Z',
    idempotencyKey: 'invoice-sync:in_123',
  }
)

Expected result

Background work runs outside the request path and can be retried safely.

Retries & Failure Handling

Durable Jobs retries transient failures, preserves completed steps, and gives failed work a clear recovery path.

Scheduling & Delayed Jobs

Run jobs later for reminders, follow-ups, retry windows, cleanup, and recurring backend work.