> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Queues

> Use queues for background execution, retry policy, delayed jobs, and concurrency control.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

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

## Prerequisites

* A StackShift client and handler route

## Workflow

<Steps>
  <Step>
    Create or choose a queue name.
  </Step>

  <Step>
    Enqueue work with a job name and payload.
  </Step>

  <Step>
    Register a matching handler.
  </Step>

  <Step>
    Set retry and delay options per job when needed.
  </Step>
</Steps>

## Enqueue jobs

<CodeGroup>
  ```ts Queue work theme={null}
  await stackshift.queue('emails').enqueue(
    'sendReceipt',
    { orderId: 'order_123', customerId: 'cus_123' },
    {
      idempotencyKey: 'receipt:order_123',
      maxAttempts: 5,
    }
  )
  ```

  ```go Go theme={null}
  _, err := client.Queue("emails").Enqueue(ctx,
    "sendReceipt",
    map[string]any{"orderId": "order_123", "customerId": "cus_123"},
    &stackshift.EnqueueOptions{
      IdempotencyKey: "receipt:order_123",
      MaxAttempts: 5,
    },
  )
  ```
</CodeGroup>

## Handlers

<CodeGroup>
  ```ts Handle queued work theme={null}
  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 }
  })
  ```

  ```go Go theme={null}
  client.Job("sendReceipt", func(ctx context.Context, job stackshift.JobContext) (any, error) {
    var payload struct {
      OrderID string `json:"orderId"`
      CustomerID string `json:"customerId"`
    }
    _ = json.Unmarshal(job.Payload, &payload)

    order, err := job.Step.Run(ctx, "load-order", func(context.Context, stackshift.HandlerInvocation) (any, error) {
      return loadOrder(payload.OrderID)
    })
    if err != nil { return nil, err }

    _, err = job.Step.Run(ctx, "send-receipt-email", func(context.Context, stackshift.HandlerInvocation) (any, error) {
      return nil, sendReceiptEmail(order)
    })
    if err != nil { return nil, err }

    return map[string]any{"sent": true}, nil
  })
  ```
</CodeGroup>

## Retries and delayed jobs

```ts Retry later theme={null}
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

<Check>
  Background work runs outside the request path and can be retried safely.
</Check>

## Related guides

<CardGroup cols={2}>
  <Card title="Retries & Failure Handling" href="/durable-jobs/retries-and-failure-handling">
    Durable Jobs retries transient failures, preserves completed steps, and gives failed work a clear recovery path.
  </Card>

  <Card title="Scheduling & Delayed Jobs" href="/durable-jobs/scheduling-and-delayed-jobs">
    Run jobs later for reminders, follow-ups, retry windows, cleanup, and recurring backend work.
  </Card>
</CardGroup>
