Inngest
Use Inngest for MainSDK events and background jobs - the default driver, main.yaml, retries, schedules, local dev server, testing and swapping.
Inngest is the default driver behind events and jobs. It runs your background jobs and schedules durably, so jobs.run() and jobs.schedule() survive restarts and retry with backoff. Inngest calls your app over HTTP to run each step, which suits serverless platforms where you have no long-running worker. Pick it unless you already run another queue.
Interfaces it serves
Pick Inngest in main.yaml for any of these. Your calls stay the same, and you can swap later.
workflowsPreviewDriver inngest Inngest
later
workflows:
driver: inngestjobsBuilding for 0.3Driver inngest Inngest
not built yet; the webhooks-jobs spec names it
jobs:
driver: inngestSwap to another provider
Before you start
- Create an Inngest account (or run Inngest yourself) and an app for each environment.
- Copy the event key (used to send events) and the signing key (used to verify Inngest's calls into your app) and store them in your secrets manager.
- Expose the endpoint Inngest calls in your app. How MainSDK mounts that endpoint on a route is not specified yet.
Configure
jobs:
driver: inngest
dead-letter: true # keep jobs that exhausted their retries
idempotency: { store: db, ttl: 24h }
# [to be decided] how the driver takes its keys; suggested names INNGEST_EVENT_KEY and INNGEST_SIGNING_KEY as secret: referencesUse it
import { auth, events, 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}`, retries: 3, backoff: "exponential" },
);
await events.publish("report.requested", { month });
return new Response(null, { status: 202 });
}Schedule recurring work with jobs.schedule("reports.nightly", "0 3 * * *", { region: "in" }).
Local development and testing
- Development: use the in-process local queue in a
main.env.dev.yamloverlay, or the Inngest Dev Server, which runs on your machine and shows each run.mainsdk checkrefuses the local queue in production. - Tests:
createTestApp()from@mainsdk/testingruns jobs on an in-memory fake,clock.advance()plays out retries without waiting, andchaos.on("jobs", { outage: true })simulates Inngest being down.
What MainSDK adds on top
- CloudEvents envelope with versioned schemas; a breaking change under the same version fails
MAIN-EVENT-0004. - Retries with backoff (5 by default, exponential) and a dead-letter queue.
- A duplicate idempotency key never runs the side effect twice, even after a worker crash.
See Events and background jobs.
Limits and notes
- The driver comes with the webhooks-jobs spec (phase 1) and is the
jobsdefault. - Job inputs are stored by Inngest; keep personal data out of inputs where an ID will do, and check that Inngest's data location fits your region (US, EU or India).
- Delivery is at least once with idempotent effects; exactly-once delivery is not promised.
Swap to or from it
jobs:
driver: vercel-queues # was inngestFAQ
Do I need a worker process? No. Inngest calls your app's endpoint, so serverless deployments work as they are.
What if I don't pass an idempotency key? One is generated from the action and its inputs.
Next
Open questions
Was this page helpful?