Best serverless workflow tools: durable execution compared
Step Functions, Temporal, Inngest, Trigger.dev and Durable Functions solve the same problem differently: keeping a long-running process alive across failures. Which suits which shape of work.
On this page
These tools exist because of one problem: a process that takes longer than a single function invocation, and must survive the machine running it disappearing halfway through.
An order that charges a card, reserves stock, books a courier and emails a customer has four steps that can each fail independently, and a partial completion is worse than no completion at all. Writing that reliably by hand means building retries, idempotency, state persistence and recovery — which is what durable execution platforms provide.
This page compares the realistic options on the axis that actually separates them: how the workflow is expressed, and who is expected to operate it.
What we'll cover
The problem these solve
Four requirements that are individually manageable and collectively a project.
Surviving process death. The machine restarts mid-workflow and the work resumes rather than vanishing or repeating.
Retrying intelligently. Step three failed because a third party was briefly unavailable. Retry that step with backoff, without repeating steps one and two.
Idempotency. A retry must not charge the card twice. Somebody has to guarantee that, and doing it properly is harder than it sounds.
Waiting. A workflow that pauses for a day awaiting approval, or a week awaiting delivery confirmation, cannot hold a running process open for that long.
Any one of these is a morning's work. All four, correct under concurrency, is a system — and it is a system that has been built enough times that buying it is sensible.
Two ways of expressing a workflow
The genuine fork in this category, and worth deciding before comparing products.
As a definition. The workflow is data — JSON, YAML, or a visual state machine — describing states and transitions. The platform interprets it. Step Functions and Google Workflows take this approach.
The advantage is that the structure is inspectable and the platform can show you exactly where an execution is. The cost is that complex logic in a definition language is unpleasant, and you end up with conditions expressed in a syntax nobody enjoys.
As code. The workflow is a function in a normal language, and the platform makes its execution durable by recording each step's result and replaying deterministically after a crash. Temporal, Inngest and Trigger.dev take this approach.
The advantage is expressiveness: loops, conditions and error handling in the language you already use, with types and tests. The cost is that the code must be deterministic, which is a genuine constraint people trip over — no random values, no current time, no direct I/O outside recorded steps.
Neither is better. Definition-based suits workflows whose shape matters more than their logic; code-based suits the reverse.
AWS Step Functions
The managed option if you are already on AWS, and the least additional operational burden of anything here.
Model: a state machine defined in JSON, with a visual editor and a visual execution view showing exactly which state an execution reached.
Strengths: deep integration with the rest of AWS, so invoking Lambda, writing to DynamoDB or publishing to SNS needs no glue. Nothing to operate. The execution view is genuinely excellent for understanding what happened. Express workflows handle high-volume short-lived cases cheaply; standard workflows handle long-running ones with full history.
Weaknesses: the definition language becomes awkward for real logic, and you will write more of it than you expect. Local testing is harder than with code-based alternatives. It binds you to AWS in a way that is difficult to unwind.
Pricing shape: per state transition for standard workflows, so the bill scales with how many steps your workflows contain rather than how long they take. Worth modelling, because a chatty workflow is an expensive one.
Choose it when you are committed to AWS and want the least to operate.
Temporal
The most capable, the most demanding, and the one large engineering organizations converge on.
Model: workflows as code in Go, Java, TypeScript, Python or .NET, with the platform recording every step and replaying deterministically after failure.
Strengths: genuinely powerful. Long-running workflows measured in months, complex signalling between workflows, versioning of running workflows, and strong guarantees. Open source, with Temporal Cloud if you would rather not operate it.
Weaknesses: a real learning curve, principally around determinism. Code inside a workflow cannot call the clock, generate randomness, or perform I/O directly, because it will be replayed — all of that belongs in activities. This trips up every team initially. Self-hosting is substantial: a server, a database, and someone who understands it.
Choose it when workflows are core to your product rather than incidental, you have engineering capacity, and you need guarantees you can reason about precisely.
Inngest and Trigger.dev
The developer-experience end of the category, aimed at teams who want durable execution without adopting a platform.
Inngest gives you event-driven functions with steps, where each step's result is memoized so a retry resumes rather than restarts. Concurrency controls, rate limiting, debouncing and fan-out are first-class, which covers a lot of real background-job needs. Local development is genuinely good.
Trigger.dev covers similar ground with an emphasis on long-running tasks, no timeout ceilings, and a strong dashboard for observing runs. Open source with a managed cloud.
Strengths for both: far quicker to adopt than Temporal, pleasant TypeScript-first ergonomics, and enough durability for the large majority of background work. The dashboards are better than the heavyweight options at showing a non-specialist what happened.
Weaknesses: less mature than Temporal for extreme cases — workflows running for months, elaborate signalling, very high scale. Smaller ecosystems.
Choose either when you want background jobs that survive failure without a platform team, and your workflows are hours or days rather than months.
Azure Durable Functions and Google Workflows
Azure Durable Functions applies the code-based replay model within Azure Functions, with orchestrator functions coordinating activity functions. The natural choice inside Azure, with the same determinism constraints as Temporal and less operational burden.
Google Workflows is definition-based, in YAML, and integrates with Google Cloud services. Lighter than Step Functions in capability and correspondingly simpler.
For either, the reason to choose it is being committed to that cloud. Neither is compelling enough to pull you onto a platform you were not already using.
The properties to check
Maximum duration. How long can one workflow run? Some cap at minutes, which rules out anything waiting on a human.
How waiting is billed. A workflow paused for three days awaiting approval should cost nothing while idle. Check this explicitly, since it is the difference between a workable pattern and an expensive one.
Versioning of running workflows. You will deploy a change while executions are mid-flight. What happens to them? Platforms differ enormously and the ones that handle it badly handle it very badly.
Local development. Can you run and debug a workflow on your machine without deploying? This affects daily life more than any headline capability.
Observability. When an execution fails at step seven of twelve, what can you see? Input and output per step, or a stack trace?
Idempotency support. What does the platform give you, and what remains your responsibility? Usually more remains yours than people assume.
Choosing
Already on AWS, want the least to operate: Step Functions.
Workflows are core to the product, you have engineering capacity: Temporal.
Background jobs that must survive failure, TypeScript team, no platform group: Inngest or Trigger.dev.
Committed to Azure or Google Cloud: their native options, for the integration rather than the capability.
None of the above, because this is a business process rather than an engineering one. Worth checking honestly. Durable execution platforms are built for workflows inside a product: charging cards, provisioning accounts, processing uploads. A process that moves information between business systems and occasionally waits for a person is a different shape of problem, and building it in Temporal is a large amount of engineering for something an automation platform handles directly. On CodeWords you describe that process in plain language and Cody, the automation builder, builds it, connects it to your systems, and deploys it, with retries and scheduling handled by the platform. Automations connect to more than 3,000 integrations. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.
Frequently asked questions
What does durable execution actually mean?
That a workflow's progress survives the process running it being killed. Each completed step is recorded, so after a crash the workflow resumes from where it reached rather than restarting or losing its place. That guarantee is the product.
Why can't I just use a queue and retries?
For simple cases you can, and it is often the right answer. The difficulty arrives with multi-step processes where a retry must not repeat earlier steps, where state must persist between them, and where a workflow waits days for an external event. That is when writing it yourself becomes a system.
What is the determinism constraint?
In code-based platforms, workflow code is re-executed during recovery, so it must produce the same path given the same recorded results. Anything non-deterministic — the current time, random values, direct network calls — must live in recorded steps rather than in the workflow body. This is the single most common source of early confusion.
Can these wait for human approval?
Yes, and it is one of the better reasons to use them. A workflow can pause for days awaiting a signal without holding a process open. Check how idle waiting is billed, because that determines whether the pattern is cheap or expensive.
Is Temporal overkill for a small team?
Usually, unless workflows are genuinely central to your product. The determinism model and the operational weight are real costs. Inngest or Trigger.dev deliver most of the durability with far less to learn and operate.
How do these differ from workflow automation tools?
These are for engineers building reliability into an application. Automation platforms are for connecting business systems, with the people who own the process doing the building. Both are called workflow tools and they serve entirely different audiences.
What happens when I deploy a change mid-execution?
It depends on the platform, and the answer matters. Some pin running executions to the version that started them, some require explicit versioning in your code, and some will simply break. Ask this before adopting, because you will hit it in the first month.
How much does observability differ between these?
More than the feature lists suggest, and it is worth weighting heavily. Step Functions' visual execution view is the clearest for showing a non-specialist exactly where a run reached. Inngest and Trigger.dev have strong dashboards for inspecting step inputs and outputs. Temporal is powerful and assumes more familiarity from whoever is reading it. You will spend more time looking at failed executions than writing new ones.
Can I move between these later?
Not cheaply. Each expresses workflows in its own model, so migration is a rewrite. Code-based platforms transfer marginally better between each other than to or from definition-based ones, since the logic is already in a language. The portable artifact, as ever, is a written description of what the process does.
Do I need one of these if I already have a queue?
Possibly not. A queue with a worker and a retry policy handles a great deal of background work perfectly well, and adding durable execution on top of it is sometimes ceremony. The threshold is multi-step processes where a retry must not repeat earlier steps and where state has to survive between them — that is where a queue stops being enough and you start writing the platform yourself.