---
title: "Amazon SQS"
description: "Use Amazon SQS for MainSDK background jobs - queues and dead-letter queues, IAM, main.yaml, the Node worker, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/amazon-sqs"
updated: "2026-10-28"
---

# Amazon SQS

> Use Amazon SQS for MainSDK background jobs - queues and dead-letter queues, IAM, main.yaml, the Node worker, testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/amazon-sqs · Updated: 2026-10-28

Amazon Simple Queue Service (SQS) is a planned driver behind [`events` and `jobs`](https://mainsdk.dev/docs/interfaces/jobs). `jobs.run()` puts work on an SQS queue, and a long-running worker takes it off, with MainSDK's retries, dead letters and idempotency on top. Pick it when your app runs on AWS with its own workers and you want jobs to stay in your account.

> **Note:** The `sqs` driver comes from the product requirements, and the webhooks-jobs spec defers it to the driver kit. It is a planned driver, not in the spec yet, so the setup below is provisional.

## Interfaces it serves

### Events and background jobs (`jobs`)

- Status: Building for 0.3 · ships as a stable API
- Driver: `sqs` (Amazon SQS, planned driver). the spec defers it to the driver kit
- Docs: https://mainsdk.dev/docs/interfaces/jobs.md

```yaml
jobs:
  driver: sqs
```

Swap to another provider: `db`, `local`, `inngest`, `vercel-queues`, `trigger-dev`.

## Before you start

1. **Create a queue** in the AWS region your app runs in. SQS offers standard queues (at-least-once, best-effort order) and FIFO queues (ordered, with deduplication). Which kinds the driver supports is [TBD].
2. **Create a dead-letter queue** for jobs that exhaust their retries, if you use `dead-letter: true`. How the driver maps MainSDK's dead-letter queue onto SQS redrive is [TBD].
3. **Give the producer and the worker IAM roles** through workload identity: the producer can send messages, the worker can receive and delete them. Avoid long-lived access keys.

## Configure

```yaml title="main.yaml"
jobs:
  driver: sqs              # [TBD] queue URL, region and other driver settings
  dead-letter: true
idempotency: { store: db, ttl: 24h }
```

## Use it

Produce a job from a route handler:

```ts title="app/api/reports/route.ts"
import { auth, jobs } from "mainsdk";

export async function POST(req: Request) {
  const session = await auth.require(req);
  const { month } = await req.json();
  await jobs.run("reports.export", { userId: session.user.id, month }, {
    idempotencyKey: `export:${session.user.id}:${month}`,
  });
  return new Response(null, { status: 202 });
}
```

Consume it in a Node worker with the worker adapter, which restores the producer's trace and user:

```ts title="worker/index.ts"
import { worker } from "mainsdk/worker";

export default worker(async (job, ctx) => {
  if (job.name === "reports.export") {   // [TBD] job object fields
    // build and send the report
  }
});
```

## Local development and testing

- **No AWS account:** use the in-process local queue in a development overlay. `mainsdk check` refuses it in production.
- **Tests:** `createTestApp()` from `@mainsdk/testing` runs jobs on an in-memory fake, `clock.advance()` plays out retries, and `chaos.on("jobs", { outage: true })` simulates SQS being unreachable.

## What MainSDK adds on top

- CloudEvents envelope with versioned schemas for events.
- Retries with backoff and a dead-letter queue.
- A duplicate idempotency key never runs the side effect twice, from MainSDK's own record, even when SQS delivers a message more than once.

See [Events and background jobs](https://mainsdk.dev/docs/interfaces/jobs).

## Limits and notes

- Planned driver, not in the spec yet: the spec defers it to the driver kit.
- SQS has no cron schedules of its own, so how `jobs.schedule()` runs on this driver is [TBD].
- A queue lives in one AWS region; pick one that fits where job inputs may be stored (US, EU or India).
- Delivery is at least once with idempotent effects.

## Swap to or from it

```yaml title="main.yaml"
jobs:
  driver: sqs   # was inngest
```

> **Warning:** Messages already on a queue stay with the old driver. What happens to queued and scheduled jobs during a swap is not specified yet [TBD]; drain the old queue first. The idempotency record moves with you, since it is MainSDK's own.

## FAQ

**Do I need a worker?** Yes. SQS holds messages; something has to poll and run them. Use the worker adapter from `mainsdk/worker`.

**Standard or FIFO?** Not decided for this driver yet. MainSDK's idempotency record makes duplicates safe on either.

## Next

- [Events and background jobs](https://mainsdk.dev/docs/interfaces/jobs)
- [Inngest](https://mainsdk.dev/docs/integrations/inngest), [Trigger.dev](https://mainsdk.dev/docs/integrations/trigger-dev) and [AWS Secrets Manager](https://mainsdk.dev/docs/integrations/aws-secrets-manager)
