Inngest Functions

Inngest functions enable developers to run reliable background logic, from background jobs to complex workflows. They provide robust tools for retrying, scheduling, and coordinating complex sequences of operations.

This page covers components of an Inngest function, as well as introduces different kinds of functions. If you'd like to learn more about Inngest's execution model, check the "How Inngest functions are executed" page.

Anatomy of an Inngest function

Let's have a look at the following Inngest function:

import { inngest } from "./client";

export default inngest.createFunction(
  // config
  { id: "import-product-images" },
  // trigger (event or cron)
  { event: "shop/product.imported" },
  // handler function
  async ({ event, step }) => {
    // Here goes the business logic
    // By wrapping code in steps, it will be retried automatically on failure
    const s3Urls = await step.run("copy-images-to-s3", async () => {
      return copyAllImagesToS3(event.data.imageURLs);
    });
    // You can include numerous steps in your function
    await step.run('resize-images', async () => {
      await resizer.bulk({ urls: s3Urls, quality: 0.9, maxWidth: 1024 });
    })
  };
);

The above code can be explained as:

This Inngest function is called import-product-images. When an event called shop/product.imported is received, run two steps: copy-images-to-s3 and resize-images.

Let's have a look at each of this function's components.

Config

The first parameter of the createFunction method specifies Inngest function's configuration. In the above example, the id is specified, which will be used to identify the function in the Inngest system.

You can see this ID in the Inngest Dev Server's function list:

Screenshot of the Inngest Dev Server interface showing three functions listed under the 'Functions' tab. The functions are: 'store-events,' 'Generate monthly report,' and 'Customer Onboarding,' each with their respective triggers and App URLs.

You can also provide other configuration options, such as concurrency, throttle, debounce, rateLimit, priority, batchEvents, or idempotency (learn more about Flow Control). You can also specify how many times the function will retry, what callback function will run on failure, and when to cancel the function.

Trigger

Inngest functions are designed to be triggered by events or crons (schedules). Events can be sent from your own code or received from third party webhooks or API requests. When an event is received, it triggers a corresponding function to execute the tasks defined in the function handler (see the "Handler" section below).

Each function needs at least one trigger. However, you can also work with multiple triggers to invoke your function whenever any of the events are received or cron schedule occurs.

Handler

A "handler" is the core function that defines what should happen when the function is triggered.

The handler receives context, which includes the event data, tools for managing execution flow, or logging configuration. Let's take a closer look at them.

event

Handler has access to the data which you pass when sending events to Inngest via inngest.send() or step.sendEvent().

You can see this in the example above in the event parameter.

step

Inngest steps are fundamental building blocks in Inngest functions. They are used to manage execution flow. Each step is a discrete task, which can be executed, retried, and recovered independently, without re-executing other successful steps.

It's helpful to think of steps as code-level transactions. If your handler contains several independent tasks, it's good practice to wrap each one in a step. In this way, you can manage complex state easier and if any task fails, it will be retried independently from others.

There are several step methods available at your disposal, for example, step.run, step.sleep(), or step.waitForEvent().

In the example above, the handler contains two steps: copy-images-to-s3 and resize-images.

Kinds of Inngest functions

Background functions

Long tasks can be executed outside the critical path of the main flow, which improves app's performance and reliability. Perfect for communicating with third party APIs or executing long-running code.

Scheduled functions

Inngest's scheduled functions enable you to run tasks automatically at specified intervals using cron schedules. These functions ensure consistent and timely execution without manual intervention. Perfect for routine operations like sending weekly reports or clearing caches.

Delayed functions

You can enqueue an Inngest function to run at a specific time in the future. The task will be executed exactly when needed without manual intervention. Perfect for actions like sending follow-up emails or processing delayed orders.

Step functions

Step functions allow you to create complex workflows. You can coordinate between multiple steps, including waiting for other events, delaying execution, or running code conditionally based on previous steps or incoming events. Each step is individually retriable, making the workflow robust against failures. Ideal for scenarios like onboarding flows or conditional notifications.

Fan-out functions

Inngest's fan-out jobs enable a single event to trigger multiple functions simultaneously. Ideal for parallel processing tasks, like sending notifications to multiple services or processing data across different systems.

Invoking functions directly

You can call an Inngest function directly from within your event-driven system by using step.invoke(), even across different Inngest SDKs.

This is useful when you need to break down complex workflows into simpler, manageable parts or when you want to leverage existing functionality without duplicating code. Direct invocation is ideal for orchestrating dependent tasks, handling complex business logic, or improving code maintainability and readability.

Further reading