Invoke v3.7.0+

Use step.invoke() to asynchronously call another function and handle the result. Invoking other functions allows you to easily re-use functionality and compose them to create more complex workflows or map-reduce type jobs. step.invoke() returns a Promise that resolves with the return value of the invoked function.

// Some function we'll call
const computeSquare = inngest.createFunction(
  { id: "compute-square" },
  { event: "calculate/square" },
  async ({ event }) => {
    return { result: event.data.number * event.data.number }; // Result typed as { result: number }
  }
);

// In this function, we'll call `computeSquare`
const mainFunction = inngest.createFunction(
  { id: "main-function" },
  { event: "main/event" },
  async ({ step }) => {
    const square = await step.invoke("compute-square-value", {
      function: computeSquare,
      data: { number: 4 }, // input data is typed, requiring input if it's needed
    });

    return `Square of 4 is ${square.result}.`; // square.result is typed as number
  }
);

step.invoke(id, options): Promise

  • Name
    id
    Type
    string
    Required
    required
    Description

    The ID of the invocation. This is used in logs and to keep track of the invocation's state across different versions.

  • Name
    options
    Type
    object
    Required
    required
    Description

    Options for the invocation:

    Properties
    • Name
      function
      Type
      InngestFunction | InngestFunctionReference
      Required
      required
      Description

      A local instance of a function or a reference to a function to invoke.

    • Name
      data
      Type
      object
      Required
      optional
      Description

      Optional data to pass to the invoked function. Will be required and typed if it can be.

    • Name
      user
      Type
      object
      Required
      optional
      Description

      Optional user context for the invocation.

    • Name
      timeout
      Type
      string | number | Date
      Required
      optional
      Version
      v3.14.0+
      Description

      The amount of time to wait for the invoked function to complete. The time to wait can be specified using a number of milliseconds, an ms-compatible time string like "1 hour", "30 mins", or "2.5d", or a Date object.

      If the timeout is reached, the step will throw an error. See Error handling below. Note that the invoked function will continue to run even if this step times out.

    Throwing errors within the invoked function will be reflected in the invoking function.

Invoke a function directly

const resultFromDirectCall = await step.invoke("invoke-by-definition", {
  function: anotherFunction,
  data: { ... },
});

Invoke a function using a function reference

const resultFromReference = await step.invoke("invoke-by-reference", {
  function: referenceFunction(...),
  data: { ... },
});

Invoke a function with a timeout

const resultFromDirectCall = await step.invoke("invoke-with-timeout", {
  function: anotherFunction,
  data: { ... },
  timeout: "1h",
});

How to call step.invoke()

Handling step.invoke() is similar to handling any other Promise in JavaScript:

// Using the "await" keyword
const result = await step.invoke("invoke-function", {
  function: someInngestFn,
  data: { ... },
});

// Using `then` for chaining
step
  .invoke("invoke-function", { function: someInngestFn, data: { ... } })
  .then((result) => {
    // further processing
  });

// Running multiple invocations in parallel
Promise.all([
  step.invoke("invoke-first-function", {
    function: firstFunctionReference,
    data: { ... },
  }),
  step.invoke("invoke-second-function", {
    function: secondFn,
    data: { ... },
  }),
]);

Using function references

Instead of directly importing a local function to invoke, referenceFunction() can be used to call an Inngest function located in another app, or to avoid importing the dependencies of a function within the same app.

import { referenceFunction } from "inngest";
import { type computePi } from "@/inngest/computePi";

// Create a local reference to a function without importing dependencies
const computePi = referenceFunction<typeof computePi>({
  functionId: "compute-pi",
});

// Create a reference to a function in another application
const computeSquare = referenceFunction({
  appId: "my-python-app",
  functionId: "compute-square",
});

// square.result is typed as a number
const square = await step.invoke("compute-square-value", {
  function: computePi,
  data: { number: 4 }, // input data is typed, requiring input if it's needed
});

See Referencing functions for more information.

When to use step.invoke()

Use of step.invoke() to call an Inngest function directly is more akin to traditional RPC than Inngest's usual event-driven flow. While this tool still uses events behind the scenes, you can use it to help break up your codebase into reusable workflows that can be called from anywhere.

Use step.invoke() in tasks that need specific settings like concurrency limits. Because it runs with its own configuration, distinct from the invoker's, you can provide a tailored configuration for each function.

If you don't need to define granular configuration or if your function won't be reused across app boundaries, use step.run() for simplicity.

Internal behaviour

When a function object is passed as an argument, internally, the SDK retrieves the function's ID automatically. Alternatively, if a function ID string is passed, the Inngest SDK will assert the ID is correct at runtime. See Error handling for more information about this point.

When Inngest receives the request to invoke a function, it'll do so and wait for an inngest/function.finished event, which it will use to fulfil the data (or error) for the step.

Return values and serialization

Similar to step.run(), all data returned from step.invoke() is serialized as JSON. This is done to enable the SDK to return a valid serialized response to the Inngest service.

Retries

The invoked function will be executed as a regular Inngest function: it will have its own set of retries and can be seen as a brand new run.

If a step.invoke() fails for any of the reasons below, it will throw a NonRetriableError. This is to combat compounding retries, such that chains of invoked functions can be executed many more times than expected. For example, if A invokes B which invokes C, which invokes D, on failure D would be run 27 times (retryCount^n).

This may change on the future - let us know if you'd like to change this.

Error handling

Function not found

If Inngest could not find a function to invoke using the given ID (see Internal behaviour above), an inngest/function.finished event will be sent with an appropriate error and the step will fail with a NonRetriableError.

Invoked function fails

If the function exhausts all retries and fails, an inngest/function.finished event will be sent with an appropriate error and the step will fail with a NonRetriableError.

Invoked function times out

If the timeout has been reached and the invoked function is still running, the step will fail with a NonRetriableError.

Usage limits

See usage limits for more details.