---
title: Lambda Durable Execution for .NET (2026): When C# Workflows Beat Step Functions
description: On July 23, 2026 AWS GA’d the Durable Execution SDK for .NET (Amazon.Lambda.DurableExecution). Score your C# workflows against our durable-vs-Step-Functions matrix. Most integration-heavy flows still belong in ASL.
url: https://www.joinhorizon.co/blog/aws-lambda-durable-execution-dotnet-2026/
datePublished: 2026-08-03T00:00:00.000Z
dateModified: 2026-10-28T00:00:00.000Z
author: manojkumar-varatharajan
category: Serverless & Containers
tags: aws, aws-lambda, durable-execution, dotnet, csharp, step-functions, serverless, architecture
---

# Lambda Durable Execution for .NET (2026): When C# Workflows Beat Step Functions

> On July 23, 2026 AWS GA’d the Durable Execution SDK for .NET (Amazon.Lambda.DurableExecution). Score your C# workflows against our durable-vs-Step-Functions matrix. Most integration-heavy flows still belong in ASL.

On **July 23, 2026**, AWS [GA'd the Lambda Durable Execution SDK for .NET](https://aws.amazon.com/about-aws/whats-new/2026/07/lambdadf-dotnet/): NuGet packages **`Amazon.Lambda.DurableExecution`** and **`Amazon.Lambda.DurableExecution.Testing`**. Python and Node already had durable handlers; this release closes the orchestration gap for **C# / .NET 8+** teams that want checkpointed multi-step workflows **in code** instead of Amazon States Language (ASL).

This post is a **decision guide**. It assumes you already know [Step Functions production patterns](https://www.joinhorizon.co/blog/aws-step-functions-workflow-orchestration-patterns/) and [serverless modernization seams](https://www.joinhorizon.co/blog/aws-serverless-modernization-playbook-2026/).

Artifacts: [durable vs Step Functions matrix](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md), [sample C# workflow outline](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/sample-durable-workflow-outline.cs).

> **First-party architecture benchmark (not a cited client):** We scored **12** illustrative .NET workflow shapes (payment capture, fraud callback, agent tool loops, nightly batch handoffs, marketing journey triggers) against the [decision matrix](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md). **3** landed on **durable .NET Lambda** (human-in-the-loop + logic-heavy C#). **7** stayed **Step Functions Standard** (visual ops, 15+ native integrations, compliance audit). **2** stayed **EventBridge Scheduler** only (single delayed invoke, no branching). Average SFN holdout had **18+** state transitions, and transition billing still wins over cramming those integrations into custom `StepAsync` wrappers.

## What durable .NET Lambda adds (Jul 2026)

Enable **durable execution** when creating the function (runtime cannot be toggled later). Handler pattern:

1. Receive `DurableExecutionInvocationInput` from the durable execution service.
2. Call `DurableFunction.WrapAsync` with typed input/output (generic `TInput` / `TOutput` overloads).
3. Inside the workflow, use `IDurableContext`: **`StepAsync`**, **`WaitAsync`**, **`WaitForCallbackAsync`**, **`ParallelAsync`**, **`MapAsync`**, **`InvokeAsync`**.

Alternative: **`[DurableExecution]`** attribute with Lambda Annotations for attribute-driven handlers.

| Primitive              | Why it matters                                                             |
| ---------------------- | -------------------------------------------------------------------------- |
| `StepAsync`            | Checkpoints a unit of work; replay skips completed steps after failure     |
| `WaitForCallbackAsync` | Human-in-the-loop / external approval up to **1 year**; execution suspends |
| `ParallelAsync`        | Fan-out branches with durable checkpoint per branch                        |
| `WrapAsync`            | Unpacks service envelope; required entry for custom bootstrap hosts       |

Use cases called out by AWS: **payment pipelines**, **AI agent orchestration**, **human-in-the-loop** approvals. These are the same themes as Step Functions Task Tokens, expressed as ordinary async C#.

## Durable .NET vs Step Functions: opinionated split

**We recommend durable .NET Lambda when** the team owns a .NET service repo, workflow rules change in pull requests, and steps are mostly **custom code** (PSP APIs, fraud scoring, LLM tool routing) with occasional long waits. You keep types, tests, and refactors in one codebase.

**We recommend Step Functions when** platform or compliance needs **Workflow Studio**, execution history in the console, **Express** volume economics, or **optimized integrations** (start Glue job, put DynamoDB item) without writing checkpoint plumbing. If your org already runs SFN with IAM-scoped operators, durable Lambda is an additive choice and not a wholesale replacement.

**We recommend EventBridge Scheduler when** the requirement is literally _"call this Lambda Tuesday at 09:00"_ with no saga; see [SES + Step Functions marketing automation](https://www.joinhorizon.co/blog/aws-ses-marketing-automation-eventbridge-step-functions-2026/) for when journeys need real state machines.

```
Client / Event ──► API Gateway or EventBridge ──► Durable .NET Lambda (alias/version)
                                                      │
                         StepAsync ──► checkpoint ──► resume on failure
                         WaitForCallbackAsync ──► suspend (no active duration on wait)
                         ParallelAsync ──► fan-out fraud / agent tools
```


![Decision diagram comparing durable .NET Lambda, Step Functions, and EventBridge Scheduler](../../assets/images/blog/aws-lambda-durable-execution-dotnet-2026-choice.webp)

_Figure: three alternatives. Durable .NET fits custom code in a .NET repo. Step Functions fits Workflow Studio, Express volume, or direct service integrations. EventBridge Scheduler fits a clock with no saga. [Open the draw.io source](https://www.joinhorizon.co/examples/architecture-blog-2026/aws-lambda-durable-execution-dotnet-2026/durable-vs-sfn.drawio)._

## Sample outline: payment + fraud callback

Illustrative only; see [sample-durable-workflow-outline.cs](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/sample-durable-workflow-outline.cs) for the full commented sketch.

_Context: .NET 8+, `Amazon.Lambda.DurableExecution` NuGet, durable execution enabled at function create, invoke via **published alias**._

```csharp
public Task<DurableExecutionInvocationOutput> HandleAsync(
    DurableExecutionInvocationInput input, ILambdaContext ctx)
    => DurableFunction.WrapAsync<PaymentRequest, PaymentResult>(RunWorkflowAsync, input, ctx);

// Inside RunWorkflowAsync:
var hold = await ctx.StepAsync(
    async (_, ct) => await PaymentGateway.AuthorizeHoldAsync(request, ct),
    name: "authorize-hold");

var review = await ctx.WaitForCallbackAsync<FraudReviewDecision>(
    timeout: TimeSpan.FromDays(3), name: "fraud-analyst-callback");
```


![Sequence diagram of API Gateway invoking a published durable .NET Lambda alias that authorizes a payment hold and waits for a fraud analyst callback](../../assets/images/blog/aws-lambda-durable-execution-dotnet-2026-callback.webp)

_Figure: invoke a published alias, not $LATEST. StepAsync authorizes a hold for ORDER-DEMO-001 with an idempotency key. The dashed arrow is the fraud callback, which suspends without active duration. [Open the draw.io source](https://www.joinhorizon.co/examples/architecture-blog-2026/aws-lambda-durable-execution-dotnet-2026/payment-callback.drawio)._

Test with **`Amazon.Lambda.DurableExecution.Testing`** and replay-aware assertions before production alias cutover.

## Hosting models and replay discipline

The C# SDK supports three entry patterns (Jul 2026 docs):

| Model                                                               | When to use                                                                                            |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Executable** (`Main` + `LambdaBootstrap`)                         | Container-style .NET 8 custom runtime, full control of serializer bootstrap                            |
| **Class library** (`Assembly::Type::Method` + `[LambdaSerializer]`) | Standard zip deploy; same `WrapAsync` handler signature                                                |
| **Lambda Annotations** (`[LambdaFunction]` + `[DurableExecution]`)  | SAM/CDK teams: source generator emits `WrapAsync` wrapper and checkpoint IAM in `serverless.template` |

Replay rules that matter on day one:

- Pass **`CancellationToken`** through every `StepAsync` body to HTTP and SDK calls; do not branch workflow logic on `IsCancellationRequested` (non-deterministic on replay).
- Use **`ctx.Logger`** instead of `Console.WriteLine`: replay-safe logging emits each line once across re-derivations.
- Mark external side effects **idempotent** (PSP idempotency keys, conditional DynamoDB writes): a retried step after partial failure must not double-charge.

For AI agent orchestration, **`ParallelAsync`** plus **`InvokeAsync`** to sibling Lambdas replaces some Step Functions Map states when tool calls stay inside the .NET service boundary, but cross-account fan-out with visual audit still favors SFN.

> **What broke:** Prototype week: team invoked the durable function via **`$LATEST`** and deployed a **StepAsync** body change mid-flight on three fraud-review executions. Replays after deploy re-ran the modified authorization branch; two holds double-submitted against the PSP sandbox. Detected via duplicate hold IDs in structured logs. **Fix:** pin **`prod` alias** to a version, freeze deploys until executions complete or fail closed, mark non-idempotent PSP calls with explicit idempotency keys inside StepAsync. **Lesson:** durable execution is replay, so treat versions like database migrations.

> **Reproduce this:** Open the [decision matrix](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md) and score your backlog workflows 0 to 2 per column. Clone the repo path `examples/architecture-blog-2026/lambda-durable-dotnet/sample-durable-workflow-outline.cs` into a .NET 8 Lambda project, add the NuGet package, enable durable execution on a **new** test function, and invoke through a **published version**, not `$LATEST`.

## Cost and ops notes

Durable Lambda bills **active compute** plus **durable operations / checkpoint storage** (see [Lambda pricing](https://aws.amazon.com/lambda/pricing/)). Waits and callbacks suspend work, unlike a Step Functions Standard workflow where **state transitions** accumulate per ASL state. For a 12-step Standard workflow at ~$0.025 per 1k transitions, run the transition math before assuming durable Lambda is cheaper; high step counts with low compute can still favor SFN or Express depending on duration.

Pair with [Lambda cost optimization](https://www.joinhorizon.co/blog/aws-lambda-cost-optimization-pay-per-request-vs-provisioned/) for memory tuning. Durable replays re-execute handler entry, and oversized memory multiplies replay cost.

## What to do this week

1. Inventory .NET workflows still implemented as **SQS + Lambda chains** or **nested Step Functions calling one C# Lambda**. These are prime durable candidates.
2. Score each against the [matrix](https://www.joinhorizon.co/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md); document tie-break rules when two columns score equally (default: keep the option already in production).
3. Spike **one** human-in-the-loop path with `WaitForCallbackAsync` on a dev alias; wire callback completion through the Lambda API per AWS docs.
4. Add **`Amazon.Lambda.DurableExecution.Testing`** replay tests for every `StepAsync` that touches external paid APIs.
5. Document **alias/version** promotion rules alongside existing [serverless modernization](https://www.joinhorizon.co/blog/aws-serverless-modernization-playbook-2026/) deploy gates.

## What this post doesn't cover

- **Full CDK/SAM/IaC templates** for durable functions: function create flags and IAM for callback APIs are account-specific
- **Cross-language durable invoke** (calling Python durable from .NET): use `InvokeAsync` patterns in SDK docs
- **Bedrock AgentCore vs durable Lambda** for net-new agents: see [Bedrock agent tool-use guide](https://www.joinhorizon.co/blog/how-to-build-amazon-bedrock-agent-tool-use-2026/)
- **Express Step Functions vs durable** TCO spreadsheet: we have not published a unified calculator; run both pricing pages against your transition count and wait profile
- **Regional availability:** confirm [Lambda durable functions regions](https://aws.amazon.com/lambda/lambda-durable-functions/) before multi-region design

We have not run a production cutover of a **Standard Step Functions** workflow with **>30** ASL states to durable .NET in a single release; treat phased migration (one branch at a time) as the safe envelope.

**Related:** [AWS serverless services](https://www.joinhorizon.co/services/aws-serverless/) · [Architecture review](https://www.joinhorizon.co/services/aws-architecture-review/) · [Generative AI on AWS](https://www.joinhorizon.co/services/generative-ai-on-aws/)

## FAQ

### When should we NOT use Lambda Durable Execution on .NET?
Skip it when ops needs edit ASL in Workflow Studio without redeploying C#, when Express Step Functions already meets volume/latency, when steps are mostly native AWS integrations (Glue, EMR, DynamoDB) better expressed in ASL, or when the team has not designed for replay-safe idempotent StepAsync bodies.

### When should we still use Step Functions instead of durable .NET Lambda?
Keep Step Functions for cross-team visual operations, Standard workflow audit history, Express high-volume short orchestration, and workflows with many optimized service integrations. SFN remains the control plane when non-developers own workflow changes.

### What goes wrong if we invoke durable functions with $LATEST?
Replays after a code deploy can run different logic than the execution started with, breaking deterministic recovery. AWS recommends published versions or aliases for production invocations. Treat $LATEST as prototype-only.

### How is durable .NET different from Python/Node durable SDKs?
Same execution model and checkpoint semantics. The .NET host uses DurableFunction.WrapAsync with DurableExecutionInvocationInput/Output envelopes and CancellationToken on every operation body. Python and Node shipped earlier; .NET closed the gap for C# shops on Jul 23, 2026.

### Can durable Lambda replace EventBridge Scheduler?
No for simple one-shot delays. Scheduler fires a target at a time with no branching. Durable Lambda is for multi-step stateful workflows with waits, callbacks, and parallel branches, not cron-only deferrals.

### Does wait time bill Lambda duration?
For on-demand functions, active duration billing pauses while the execution waits (timer or callback). You still pay for durable operation and checkpoint storage per AWS pricing; verify the current Lambda durable functions rate card before budgeting long human-in-the-loop flows.

---

*Source: https://www.joinhorizon.co/blog/aws-lambda-durable-execution-dotnet-2026/*
