Content

Best Durable Execution Platforms for AI Agents

Temporal, Inngest, and Restate replay the workflow. Replaying the workflow is not the same as a safe retry of the provider call inside it.

EngineeringOct 16, 2026

Key takeaways

  • -In this article we explore the best durable execution platforms for AI agents, and why a replay is not the same as a safe retry.
  • -To understand how durable execution works: the platform remembers the workflow and runs it forward after a crash. That does not, by itself, make a provider write safe to repeat.
  • -Temporal replays workflow code and expects activities to be careful about side effects. Inngest retries steps. Restate retries invocations.
  • -A replay that sends the provider call again is a second charge, a second email, or a second ticket unless that call carries the same idempotency key.
  • -Swytchcode is not a workflow engine. It is the execution layer the activity should call, so the retry rule lives on the API request.

Durable execution keeps a workflow going after the process dies. The platform stores how far the run got and continues from there, or rebuilds the run by replaying the code that already happened. That is what you want for an agent that books a set of steps and must not forget step three because a worker restarted.

It is not what makes step three safe. Step three called an API. If the replay or the retry runs that call again, the provider does it again, unless the call itself is idempotent. Replaying the workflow and retrying the provider are different boundaries. Mixing them up is how a reliable-looking agent charges twice. This page separates the platforms that own the workflow from the runtime that should own the API call.

What replay actually repeats

A durable platform records decisions. "This step finished and returned this value" can be replayed from the record, without doing the work again. "This step was started and we never stored the result" cannot. The platform runs the step again.

That second case is normal. The worker died after the provider accepted the request and before your code saved the response. The durable platform's correct behaviour is to run the step again. The provider's correct behaviour, if you send a new request, is to perform the action again. Both are working. The customer still got two refunds, two emails, or two records.

The idempotency key has to be on the provider request, stable across those attempts, and stored by the provider or by the client that will not forget it. The workflow id is not that key unless you deliberately send it as one. A new key generated inside the step is a new write on every replay.

The platforms

Temporal. The reference for this category. Workflow code must be deterministic. Temporal replays it to rebuild state. Side effects belong in activities, which are not replayed as workflow code. They are retried as activities. You are expected to make activities safe to run more than once. Temporal will not add a Stripe idempotency key for you. If the activity builds a new HTTP request on each attempt, Temporal's reliability is what causes the duplicate. Use Temporal when the workflow is long, has real compensation logic, and is worth operating a cluster for. Put the provider call in an activity that cannot mint a new write.

Inngest. Event-driven steps, aimed at TypeScript and serverless. A function is broken into steps. A failed step retries. Completed steps are not run again. The dangerous window is the same: a step that called the provider, crashed before reporting success, and is retried. Inngest is the right weight when you do not want to run Temporal and the flow is "on this event, do these steps." It is not a substitute for an idempotency key on the step that sends mail or moves money.

Restate. Durable handlers and virtual objects. Invocations are retried. State for a key is stored so the handler can continue. The model is a good fit for a session or a user-shaped agent loop that must survive a restart. The provider call inside the handler is still your call. Restate remembering that the handler started is not Restate remembering that the provider finished.

Trigger.dev, Hatchet, and DBOS. The same shape under different packaging. Trigger.dev and Hatchet retry tasks in the background. DBOS stores the workflow in a database and resumes it. All of them are good at "run this again if we are not sure it finished." None of them are the provider's deduplication store. Read the task that performs the write and ask what key the second attempt sends. If the answer is "a new one," the platform is working and the write is not safe.

A queue with retries (SQS, Cloud Tasks, a homemade worker) is durable execution with less of a programming model. The message comes back. Your handler runs again. Same rule.

What these platforms are for

Use them when the agent's work is a sequence that outlives one process: wait for a person, call three systems, give up after a day, record the outcome. The platform is better than a script at remembering the sequence. Teams that put the HTTP client inside the first version of the activity get exactly this benefit and exactly the duplicate-write bug.

Do not use them as the policy engine for which API method an agent may call, and do not use them as the credential store. A workflow that has the API key in its payload will replay that payload. The key is now in the workflow history. Credentials belong on the call, attached by a runtime, not in the event.

The provider retry is a different product

Swytchcode is not a durable execution platform. It will not resume your workflow after a crash, and it should not be picked from this list for that job. It is the execution kernel the activity, step, or handler should call when the step needs a real API.

The model, or the workflow, names the method. The runtime checks the allow list, validates the input, evaluates policy before injecting the credential, and sends the request from your machine. Sandbox or production is the project mode in tooling.json. Retries back off on rate limits. A POST or PATCH is retried only when an idempotency key is set, and that key is reused. The response is validated on the way back. A replayed activity that calls the same exec is the same write. A replayed activity that builds a fresh HTTP request is not. The detail is in How Swytchcode Retries Failed API Calls and Idempotency Explained. The stages around that call are in AI agent execution layer architecture.

Discover the method in the project when you wire the activity. Do not hardcode a catalog id. Ids change.

If the agent loop is the Anthropic Agent SDK rather than a workflow engine, you have the same split at a smaller scale. The SDK runs the tool at least once. The provider call still needs the key. See Making Anthropic Agent SDK Tool Calls Idempotent.

How to place them

Orchestration in Temporal, Inngest, or Restate. One activity per provider write. That activity calls the execution layer and returns the normalized result. The workflow stores the result. On replay, a finished activity is not sent again. An unfinished activity is sent again through the same exec, with the same idempotency key.

Do not let the workflow call the provider SDK directly "because it is faster to demo." That is the path that generates a new request on every retry. Do not let the execution layer replace the workflow engine either. A single API call does not need Temporal. A two-day process with a human approval in the middle does not fit inside one exec.

FAQ

What is durable execution?

A platform that stores the progress of a workflow and continues it after a crash, by replay or by retrying the unfinished step. The workflow survives. Side effects survive only if each side effect is safe to run again.

Why is replay not a safe provider retry?

Replay runs your code again when the result was never recorded. If that code sends a new provider request, the provider performs a new action. The workflow engine did what it promised. The duplicate is in the request, not in the replay.

Temporal or Inngest?

Temporal when the workflow is long, needs a real operations model, and you will write deterministic workflow code with activities for side effects. Inngest when the work is event-driven steps and you want less infrastructure. Neither one idempotently calls Stripe for you.

Where should the idempotency key be created?

Once, from the business action, and then reused on every attempt of that action. Generating it inside the activity on each try gives every replay a new key. The provider then treats every replay as new.

Does Swytchcode replace Temporal?

No. Temporal remembers the workflow. Swytchcode runs one API call under an allow list, policy, and a retry rule that will not double-apply a write. Call it from the activity. Do not ask it to be the workflow engine.

More content