Inngest functions use a deterministic replay model. An Inngest function is called multiple times per run—once for each step (or group of parallel steps) that needs to execute.
Each time the function is called, it replays from the top. The SDK uses StepMemos (memoized results) to skip steps that have already completed. When the SDK encounters a step with no memo, it either executes the step or 'plans' it (for parallel or deferred execution) and then interrupts the function to return control to the Inngest server.
**Key behaviors:
- Deterministic code is ideal: The SDK works best when steps appear in the same order on every replay.
- Non-determinism handling: If a new step appears without a memo, it runs. If a memoized step is no longer encountered, its memo is ignored.
- Error condition: An error occurs if step targeting is active and the targeted step is not found during replay.
@client.create_function(
fn_id="my-fn",
trigger=inngest.TriggerEvent(event="app/signup"),
)
async def my_fn(ctx: inngest.Context) -> str:
user = await ctx.step.run("create-user", create_user) # Step A
await ctx.step.run("send-email", lambda: send_email(user)) # Step B
return "done"