Durable Execution SDK for .NET β Preview Now Available π
The AWS Lambda .NET team is excited to announce the preview of the AWS Lambda Durable Execution SDK for .NET (Amazon.Lambda.DurableExecution).
Durable Execution lets you build resilient, long-running Lambda functions that automatically checkpoint their progress and resume after failures. Workflows can run for up to one year, and you're only charged for active compute time β not for the time spent waiting.
Why Durable Execution?
Today, orchestrating multi-step workflows in Lambda often means stitching together Step Functions state machines, SQS queues, or DynamoDB-backed state, and writing your own logic to track progress and recover from failures. Durable Execution lets you express that same workflow as ordinary C# code β await your steps, your waits, and your callbacks β while the SDK handles checkpointing, retries, and replay-safe resumption for you.
Key features
- Automatic checkpointing β progress is saved after each step; failures resume from the last checkpoint.
- Cost-effective waits β suspend execution for minutes, hours, or days without compute charges.
- Configurable retries β built-in retry strategies with exponential backoff and jitter.
- Replay safety β functions deterministically resume from checkpoints after interruptions.
- Type safety β full generic type support for step results.
- AOT-friendly β pluggable
ILambdaSerializer for trimmed / Native AOT functions.
For example, a multi-step order workflow with a built-in wait becomes:
private async Task<OrderResult> Workflow(Order order, IDurableContext ctx)
{
var reservation = await ctx.StepAsync(
async (_, ct) => await InventoryService.ReserveAsync(order.Items, ct),
name: "reserve-inventory");
var payment = await ctx.StepAsync(
async (_, ct) => await PaymentService.ChargeAsync(order.PaymentMethod, order.Total, ct),
name: "process-payment");
// Suspend for 2 hours with no compute charges, then resume.
await ctx.WaitAsync(TimeSpan.FromHours(2), name: "warehouse-processing");
var shipment = await ctx.StepAsync(
async (_, ct) => await ShippingService.ShipAsync(reservation, order.Address, ct),
name: "confirm-shipment");
return new OrderResult(order.Id, shipment.TrackingNumber);
}
The first preview is available on NuGet:
π¦ Amazon.Lambda.DurableExecution 0.0.1-preview
dotnet add package Amazon.Lambda.DurableExecution --version 0.0.1-preview
Preview status. Amazon.Lambda.DurableExecution is in active development (0.x). Public APIs may change before 1.0.
Deployment (preview). Currently, durable functions must be deployed as a container image. This is a temporary restrictions till the .NET managed runtimes are added to the durable function allow list. Functions must also be written using the executable programming model so that you can include the latest version of the Amazon.Lambda.RuntimeSupport package. The example below builds on the public.ecr.aws/lambda/dotnet:10 base image.
Deploying a durable function (container image)
The end-to-end integration tests build, deploy, and invoke durable functions exactly this way. See DurableFunctionDeployment.cs for the full lifecycle (IAM role β ECR repo β image build/push β CreateFunction β invoke), and the TestFunctions/ folder for runnable example functions (each paired with a test).
1. Project file β build an executable named bootstrap:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Exe</OutputType>
<AssemblyName>bootstrap</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.DurableExecution" Version="0.0.1-preview" />
<PackageReference Include="Amazon.Lambda.RuntimeSupport" Version="*" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="*" />
</ItemGroup>
</Project>
2. Dockerfile β base on the .NET 10 managed base image and run bootstrap:
FROM public.ecr.aws/lambda/dotnet:10
COPY bin/publish/ ${LAMBDA_TASK_ROOT}
ENTRYPOINT ["/var/task/bootstrap"]
3. Publish, build, and push the image:
# Publish a framework-dependent Linux build into bin/publish/
# (--self-contained false: the dotnet:10 base image supplies the runtime)
dotnet publish -c Release -r linux-x64 --self-contained false -o bin/publish
# Build the container image
docker build --platform linux/amd64 --provenance=false -t <account>.dkr.ecr.<region>.amazonaws.com/my-durable-fn:latest .
# Authenticate to ECR and push
aws ecr get-login-password --region <region> \
| docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com
docker push <account>.dkr.ecr.<region>.amazonaws.com/my-durable-fn:latest
4. Create the function with PackageType = Image and a DurableConfig. The execution role needs both the basic execution policy and the durable execution policy:
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy
await lambdaClient.CreateFunctionAsync(new CreateFunctionRequest
{
FunctionName = "my-durable-fn",
PackageType = PackageType.Image,
Role = roleArn,
Code = new FunctionCode { ImageUri = imageUri },
Timeout = 30,
MemorySize = 256,
DurableConfig = new DurableConfig { ExecutionTimeout = 60 }
});
5. Invoke it with a DurableExecutionName, then track it via GetDurableExecution / GetDurableExecutionHistory:
await lambdaClient.InvokeAsync(new InvokeRequest
{
FunctionName = "my-durable-fn",
Qualifier = "$LATEST",
Payload = payload,
DurableExecutionName = $"order-{Guid.NewGuid():N}"
});
Core operations
Your handler delegates to DurableFunction.WrapAsync, which gives your workflow an IDurableContext β your interface to durable operations:
- Steps β execute code with automatic checkpointing, retry strategies, and at-least/at-most-once semantics.
- Wait β pause execution without compute charges.
- Wait For Condition β poll until a condition is met, suspending between polls.
- Callbacks β wait for external systems (approvals, webhooks) to respond.
- Child Contexts β group related operations into isolated, checkpointed units.
π Learn more in the Durable Execution SDK README, which includes a complete getting-started walkthrough and a full Main + handler example.
Related SDKs
Durable Execution is available across multiple languages:
What's still to come π§
This is an early preview and we're actively building. On the roadmap:
We want your feedback π
We cannot overstate how critical your feedback is during preview. Please try it out and let us know what works, what doesn't, and what you'd like to see before 1.0 β comment on this issue!
Durable Execution SDK for .NET β Preview Now Available π
The AWS Lambda .NET team is excited to announce the preview of the AWS Lambda Durable Execution SDK for .NET (
Amazon.Lambda.DurableExecution).Durable Execution lets you build resilient, long-running Lambda functions that automatically checkpoint their progress and resume after failures. Workflows can run for up to one year, and you're only charged for active compute time β not for the time spent waiting.
Why Durable Execution?
Today, orchestrating multi-step workflows in Lambda often means stitching together Step Functions state machines, SQS queues, or DynamoDB-backed state, and writing your own logic to track progress and recover from failures. Durable Execution lets you express that same workflow as ordinary C# code β
awaityour steps, your waits, and your callbacks β while the SDK handles checkpointing, retries, and replay-safe resumption for you.Key features
ILambdaSerializerfor trimmed / Native AOT functions.For example, a multi-step order workflow with a built-in wait becomes:
The first preview is available on NuGet:
π¦ Amazon.Lambda.DurableExecution
0.0.1-previewDeploying a durable function (container image)
The end-to-end integration tests build, deploy, and invoke durable functions exactly this way. See
DurableFunctionDeployment.csfor the full lifecycle (IAM role β ECR repo β image build/push βCreateFunctionβ invoke), and theTestFunctions/folder for runnable example functions (each paired with a test).1. Project file β build an executable named
bootstrap:2. Dockerfile β base on the .NET 10 managed base image and run
bootstrap:3. Publish, build, and push the image:
4. Create the function with
PackageType = Imageand aDurableConfig. The execution role needs both the basic execution policy and the durable execution policy:arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRolearn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy5. Invoke it with a
DurableExecutionName, then track it viaGetDurableExecution/GetDurableExecutionHistory:Core operations
Your handler delegates to
DurableFunction.WrapAsync, which gives your workflow anIDurableContextβ your interface to durable operations:π Learn more in the Durable Execution SDK README, which includes a complete getting-started walkthrough and a full
Main+ handler example.Related SDKs
Durable Execution is available across multiple languages:
What's still to come π§
This is an early preview and we're actively building. On the roadmap:
ParallelAsyncβ fan out and run multiple durable branches concurrently.MapAsyncβ apply a durable operation across a collection of items.[DurableExecution]-style attributes.dotnet newtemplate to scaffold a durable function.We want your feedback π
We cannot overstate how critical your feedback is during preview. Please try it out and let us know what works, what doesn't, and what you'd like to see before
1.0β comment on this issue!