Durable Workflows

Write complex workflows as code and let Inngest handle the rest. Inngest manages state, retries, logging and observability for you.

Hero image for Durable Workflows
Graphic of Run steps in series or parallel

Run steps in series or parallel

Easily run parts of your workflow code in parallel, event on serverless. Always retried automatically on error.

Graphic of Durable sleep for hours *or* weeks

Durable sleep for hours *or* weeks

Pause your function and schedule to resume it after a specific period of time. Your code stops running and Inngest resumes it when the time is right.

Graphic of Visual debugging and observability

Visual debugging and observability

Our visual function timeline UI makes debugging easier than ever. See exactly what happened in your function, and when without grepping logs.

Create complex workflows with simple primitives

Chain steps that automatically retry

1 Decouple logic into discrete steps

2 Steps that fail are retried automatically

3 Steps that succeed are never re-run, saving time and money

4 Step output is captured as state, and can be used in subsequent steps

You can skip managing multiple queues and workers and persisting state of jobs in your database. Inngest takes care of that for you.

1export const processVideo = inngest.createFunction(
2  {
3    name: "Process video upload", id: "process-video",
4  },
5  { event: "video.uploaded" },
6  async ({ event, step }) => {
7    const transcript = await step.run('transcribe-video', async () => {
8      return deepgram.transcribe(event.data.videoUrl);
9    });
10    const summary = await step.run('summarize-transcript', async () => {
11      return llm.createCompletion({
12        model: "gpt-3.5-turbo",
13        prompt: createSummaryPrompt(transcript),
14      });
15    });
16    await step.run('write-to-db', async () => {
17      await db.videoSummaries.upsert({
18        videoId: event.data.videoId,
19        transcript,
20        summary,
21      });
22    });
23  }

Long running, durable workflows

1 Trigger workflows with events

2 Sleep for hours, days or longer

3 Your code stops running and Inngest resumes it when the time is right

Write idomatic code that might need to execute over a long period of time. There is no need to combine and manage crons, queues, and database state.

1export const handlePayments = inngest.createFunction(
2  {
3    name: "Handle payments", id: "handle-payments"
4  },
5  { event: "api/invoice.created" },
6  async ({ event, step }) => {
7    // Wait until the next billing date
8    await step.sleepUntil("wait-for-billing-date", event.data.invoiceDate);
10    // Steps automatically retry on error, and only run
11    // once on success - automatically, with no work.
12    const charge = await step.run("charge", async () => {
13      return await stripe.charges.create({
14        amount: event.data.amount,
15      });
16    });
18    await step.run("update-db", async () => {
19      await db.payments.upsert(charge);
20    });
22    await step.run("send-receipt", async () => {
23      await resend.emails.send({
24        to: event.user.email,
25        subject: "Your receipt for Inngest",
26      });
27    });
28  }

With Inngest, Vercel and Next.js developers can now go beyond request-response, and orchestrate complex business processes, like a recurring subscription that involves retrying payments, sending notifications, exponential backoff, human-in-the-loop intervention and more.

Image of Guillermo Rauch
Guillermo Rauch
CEO of Vercel

Everything you need to build

Automatic retries

Every step of your function is retried whenever it throws an error. Customize the number of retries to ensure your functions are reliably executed.

Durable sleep

Pause your function for hours, days or weeks with step.sleep() and step.sleepUntil(). Inngest stores the state of your functions and resumes execution automatically exactly when it should.

Declarative job cancellation

Cancel jobs just by sending an event. No need to keep track of running jobs, Inngest can automatically match long running functions with cancellation events to kill jobs declaratively.

Pause functions for additional input

Use step.waitForEvent() to pause your function until another event is received. Create human-in the middle workflows or communicate between long running jobs with events.

Replay functions

Forget dead letter queues. Fix your issues then replay a failed function in a single click.