Durable Execution SDK for .NET β Now Generally Available π
The AWS Lambda .NET team is excited to announce the general availibility 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.
https://aws.amazon.com/blogs/developer/aws-durable-execution-sdk-for-net-now-generally-available/
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 package is available on nuget
π¦ Amazon.Lambda.DurableExecution
dotnet add package Amazon.Lambda.DurableExecution
Deployment. Durable functions deploy as a plain zip package on the managed dotnet10 runtime β Both the executable programming model (a Main that builds a LambdaBootstrap) and the class-library programming model (a plain Handler method, the same model used by non-durable functions) are supported.
Deploying a durable function (zip on the managed runtime)
The end-to-end integration tests build, deploy, and invoke durable functions exactly this way. See DurableFunctionDeployment.cs for the full lifecycle (IAM role β dotnet publish β zip β CreateFunction β invoke), and the TestFunctions/ folder for runnable example functions (each paired with a test).
1. Project file β choose either programming model.
Executable model β 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.1.1-preview" />
<PackageReference Include="Amazon.Lambda.RuntimeSupport" Version="*" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="*" />
</ItemGroup>
</Project>
Class-library model β a normal Lambda class library (no OutputType, no RuntimeSupport reference); the managed runtime supplies the bootstrap loop:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AWSProjectType>Lambda</AWSProjectType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.DurableExecution" Version="0.1.1-preview" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="*" />
</ItemGroup>
</Project>
2. Handler β the executable model wires up LambdaBootstrap in Main; the class-library model declares the serializer with an assembly attribute and exposes a plain Handler.
Executable model:
public class OrderProcessor
{
public static async Task Main()
{
var handler = new OrderProcessor();
var serializer = new DefaultLambdaJsonSerializer();
using var wrapper = HandlerWrapper.GetHandlerWrapper<DurableExecutionInvocationInput, DurableExecutionInvocationOutput>(
handler.Handler, serializer);
using var bootstrap = new LambdaBootstrap(wrapper);
await bootstrap.RunAsync();
}
public Task<DurableExecutionInvocationOutput> Handler(
DurableExecutionInvocationInput input, ILambdaContext context)
=> DurableFunction.WrapAsync<Order, OrderResult>(Workflow, input, context);
private async Task<OrderResult> Workflow(Order order, IDurableContext ctx) { /* ... */ }
}
Class-library model:
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
namespace OrderProcessor;
public class Function
{
public Task<DurableExecutionInvocationOutput> Handler(
DurableExecutionInvocationInput input, ILambdaContext context)
=> DurableFunction.WrapAsync<Order, OrderResult>(Workflow, input, context);
private async Task<OrderResult> Workflow(Order order, IDurableContext ctx) { /* ... */ }
}
3. Publish and zip the package:
# Publish a framework-dependent Linux build (the dotnet:10 managed runtime supplies the runtime)
dotnet publish -c Release -r linux-x64 --self-contained false -o bin/publish
# Zip the publish output (no top-level folder)
cd bin/publish && zip -r ../function.zip . && cd -
4. Create the function as a zip package on the managed dotnet10 runtime, with 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",
Runtime = "dotnet10",
// Executable model: "bootstrap".
// Class-library model: an Assembly::Namespace.Type::Method string,
// e.g. "OrderProcessor::OrderProcessor.Function::Handler".
Handler = "bootstrap",
Role = roleArn,
Code = new FunctionCode { ZipFile = new MemoryStream(File.ReadAllBytes("bin/function.zip")) },
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 full examples of both the executable and class-library programming models.
Related SDKs
Durable Execution is available across multiple languages:
We want your feedback π
We cannot overstate how critical your feedback is. Please try it out and let us know what works, what doesn't, and what you'd like to see
Durable Execution SDK for .NET β Now Generally Available π
The AWS Lambda .NET team is excited to announce the general availibility 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.
https://aws.amazon.com/blogs/developer/aws-durable-execution-sdk-for-net-now-generally-available/
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 package is available on nuget
π¦ Amazon.Lambda.DurableExecution
Deploying a durable function (zip on the managed runtime)
The end-to-end integration tests build, deploy, and invoke durable functions exactly this way. See
DurableFunctionDeployment.csfor the full lifecycle (IAM role βdotnet publishβ zip βCreateFunctionβ invoke), and theTestFunctions/folder for runnable example functions (each paired with a test).1. Project file β choose either programming model.
Executable model β build an executable named
bootstrap:Class-library model β a normal Lambda class library (no
OutputType, noRuntimeSupportreference); the managed runtime supplies the bootstrap loop:2. Handler β the executable model wires up
LambdaBootstrapinMain; the class-library model declares the serializer with an assembly attribute and exposes a plainHandler.Executable model:
Class-library model:
3. Publish and zip the package:
4. Create the function as a zip package on the managed
dotnet10runtime, with 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 full examples of both the executable and class-library programming models.
Related SDKs
Durable Execution is available across multiple languages:
We want your feedback π
We cannot overstate how critical your feedback is. Please try it out and let us know what works, what doesn't, and what you'd like to see