---
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.factualminds.com/blog/aws-lambda-durable-execution-dotnet-2026/
datePublished: 2026-08-03T00:00:00.000Z
dateModified: 2026-08-03T00:00:00.000Z
author: palaniappan-p
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**, not a SDK tutorial. It assumes you already know [Step Functions production patterns](/blog/aws-step-functions-workflow-orchestration-patterns/) and [serverless modernization seams](/blog/aws-serverless-modernization-playbook-2026/).

Artifacts: [durable vs Step Functions matrix](https://www.factualminds.com/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md), [sample C# workflow outline](https://www.factualminds.com/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.factualminds.com/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 — 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 — same themes as Step Functions Task Tokens, but 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 — 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](/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
```

## Sample outline — payment + fraud callback

Illustrative only; see [sample-durable-workflow-outline.cs](https://www.factualminds.com/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");
```

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 — treat versions like database migrations.

> **Reproduce this** — Open the [decision matrix](https://www.factualminds.com/examples/architecture-blog-2026/lambda-durable-dotnet/durable-vs-step-functions-matrix.md) and score your backlog workflows 0–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](/blog/aws-lambda-cost-optimization-pay-per-request-vs-provisioned/) for memory tuning — durable replays re-execute handler entry; 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** — prime durable candidates.
2. Score each against the [matrix](https://www.factualminds.com/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](/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](/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](/services/aws-serverless/) · [Architecture review](/services/aws-architecture-review/) · [Generative AI on AWS](/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.factualminds.com/blog/aws-lambda-durable-execution-dotnet-2026/*
