AWS Lambda is attractive for .NET applications because it removes the need to manage servers while automatically scaling execution environments.
For ordinary Lambda functions, cold starts are already an important performance consideration. For durable workflows, the problem becomes more interesting because a workflow can execute multiple steps, pause, resume, retry failed operations, and potentially run for a long period.
AWS announced general availability of the AWS Lambda Durable Execution SDK for .NET in July 2026. The SDK provides C# developers with durable steps, waits, callbacks, durable Lambda invocation, and local testing capabilities.
That creates an important performance question for .NET teams:
How much startup overhead does a durable workflow introduce, and how does that overhead compare with the actual work performed by the workflow?
This article presents a practical benchmarking methodology rather than claiming a universal cold-start number. Actual latency depends on runtime version, memory configuration, deployment package, initialization code, workload, concurrency, and AWS environment.
What Is a Lambda Cold Start?
A cold start occurs when Lambda needs to create a new execution environment before running the function.
A simplified lifecycle is:
Incoming Request
|
v
Create Execution Environment
|
v
Initialize Runtime
|
v
Initialize Application
|
v
Run Handler
Lambda describes the initialization phase as including environment setup, runtime startup, code loading, and initialization code outside the handler. A reused environment can avoid this initialization work and is commonly referred to as a warm invocation.
For a latency-sensitive API, this distinction matters:
Cold invocation
----------------
Request
|
+--> Initialization
|
+--> Handler
|
v
Response
versus:
Warm invocation
----------------
Request
|
+--> Handler
|
v
Response
The benchmark should measure these separately.
What Changes With Durable Workflows?
A durable Lambda function is still a Lambda function, but the execution model adds checkpointing and replay.
AWS describes durable functions as using checkpoints to record workflow progress. When execution resumes, the function can replay from the beginning while skipping already-completed operations using their stored results.
The conceptual flow becomes:
Invocation
|
v
Step 1
|
v
Checkpoint
|
v
Step 2
|
v
Checkpoint
|
v
Wait
|
v
Invocation ends
|
...
|
v
Resume
|
v
Replay
|
v
Continue from checkpoint
This means a durable workflow can have multiple Lambda invocations over its lifetime.
Consequently, measuring only the first invocation does not tell the whole performance story.
The Benchmarking Question
A useful benchmark should answer several questions:
How long does a cold durable invocation take?
How long does a warm invocation take?
How much initialization time comes from the .NET application?
Does workflow configuration materially affect startup?
How much latency is introduced when a workflow resumes?
How does deployment package size affect initialization?
Does Native AOT change startup behavior?
How does memory configuration affect latency?
How does concurrency change cold-start frequency?
What portion of total workflow latency comes from cold starts versus business operations?
The goal is to separate these variables instead of producing one misleading benchmark number.
Benchmark Standard Lambda and Durable Lambda Separately
Start with two functions:
Function A
-----------
Standard .NET Lambda
Simple handler
Function B
-----------
Durable .NET Lambda
Equivalent business logic
The business operation should be as similar as possible.
For example:
Input
|
v
Validate
|
v
Calculate
|
v
Return
Then create a durable version:
Input
|
v
Durable Step: Validate
|
v
Durable Step: Calculate
|
v
Return
This comparison does not prove that one architecture is universally faster.
It tells you what overhead exists for your particular implementation.
Measure More Than End-to-End Latency
A single number such as:
Duration = 850 ms
does not explain the result.
Capture at least:
Request timestamp
Initialization duration
Handler duration
Total duration
Cold/warm classification
Memory configuration
Runtime version
Package size
Concurrency
Workflow step count
For durable workflows, also record:
Checkpoint operations
Replay events
Wait duration
Resume latency
Retry count
The benchmark should make it possible to distinguish:
Runtime startup
+
Application initialization
+
Durable execution overhead
+
Business logic
+
External service latency
Use a Repeatable Benchmark
A practical test matrix could be:
| Variable | Values |
|---|
| Function type | Standard / Durable |
| Memory | Several selected configurations |
| Deployment | ZIP / container where relevant |
| Compilation | JIT / Native AOT where supported |
| Workflow | 1 / 3 / 5 steps |
| Invocation | Cold / Warm |
| Concurrency | Low / Medium / High |
| External calls | None / Controlled dependency |
Do not change multiple variables without recording them.
For example, comparing:
Standard .NET 8
256 MB
ZIP
against:
Durable .NET
1024 MB
Container
Native AOT
does not isolate durable execution overhead.
Build a Minimal .NET Function First
Start with the smallest possible handler.
public class Function
{
public string FunctionHandler(string input)
{
return $"Processed: {input}";
}
}
This gives you a baseline for runtime and application initialization.
Then gradually add:
AWS SDK
Dependency Injection
Configuration
Logging
Database client
HTTP client
Business services
Durable SDK
Measure after each significant change.
This helps identify which dependencies are responsible for startup overhead.
Static Initialization Matters
.NET Lambda applications often initialize dependencies before the handler executes.
For example:
public class Function
{
private static readonly AmazonDynamoDBClient Client =
new();
public async Task<string> FunctionHandler(
string id)
{
// Business logic
return await Task.FromResult(id);
}
}
The static initialization can become part of startup work.
AWS recommends optimizing static initialization because imports, libraries, configuration, and connection setup can contribute to Lambda initialization latency.
The benchmark should therefore distinguish:
Runtime Initialization
+
Static Application Initialization
from:
Handler Execution
Benchmark Deployment Package Size
Package size can affect initialization behavior.
Create controlled versions:
Version A
---------
Minimal dependencies
Version B
---------
AWS SDK + application libraries
Version C
---------
Full production dependency set
Do not optimize package size blindly.
The goal is to determine whether a dependency materially affects your application's startup path.
A useful experiment is:
Package Size
|
v
Cold Start
rather than:
Package Size
|
v
Assumed Performance
Measure the relationship.
Benchmark Memory Configuration
Lambda allocates more CPU capacity as memory configuration increases.
Therefore, test several memory settings rather than assuming that the lowest memory value is the cheapest overall configuration.
For example:
| Memory | Cold p50 | Warm p50 | p95 | Cost/Invocation |
|---|
| Configuration A | Measure | Measure | Measure | Measure |
| Configuration B | Measure | Measure | Measure | Measure |
| Configuration C | Measure | Measure | Measure | Measure |
| Configuration D | Measure | Measure | Measure | Measure |
The actual values should come from your workload.
The useful question is:
Where is the latency/cost trade-off for this application?
AWS recommends performance testing for .NET Lambda workloads because application behavior and initialization characteristics vary.
Benchmark Native AOT
For .NET applications where startup latency matters, Native AOT is an important comparison.
AWS documents that .NET 8 Lambda functions can be compiled using Native AOT and that this can reduce cold-start time by removing runtime compilation work.
Create two otherwise equivalent builds:
Build A
-------
Regular .NET deployment
Build B
-------
Native AOT
Measure:
Cold initialization
Warm invocation
Package characteristics
Memory behavior
Function correctness
Do not assume Native AOT will always be the best choice.
It can introduce compatibility and trimming considerations, so functional testing is required alongside performance testing.
Benchmark SnapStart Where Applicable
AWS Lambda SnapStart is another startup optimization available for supported runtimes, including .NET. AWS describes SnapStart as restoring an initialized execution environment from an encrypted snapshot instead of performing the full initialization sequence for each new environment.
For .NET, AWS also documents runtime hooks that can be used to perform initialization before snapshot creation.
A broader experiment can therefore compare:
Standard
|
+--> Cold Start
Native AOT
|
+--> Cold Start
SnapStart
|
+--> Restore Latency
The benchmark should verify which optimizations are supported by the exact runtime and durable-function configuration being evaluated before drawing conclusions.
Durable Workflow Benchmark
Now introduce a durable workflow.
Conceptually:
Input
|
v
Step 1: Validate
|
v
Step 2: Process
|
v
Step 3: Persist
|
v
Result
Each durable step becomes a checkpointed unit of work.
AWS documents that a step checkpoints its result and that replay can use the stored result rather than executing the completed step again. This is also why non-deterministic operations should generally be placed inside steps.
The benchmark should measure:
Initial invocation
+
Step execution
+
Checkpointing
+
Resume invocation
+
Replay
+
Final completion
Why Step Count Matters
Compare:
Workflow A
-----------
1 durable step
with:
Workflow B
-----------
3 durable steps
and:
Workflow C
-----------
5 durable steps
This helps identify how workflow granularity affects total execution behavior.
A simple table:
| Workflow | Steps | Cold Start | Total Duration | Checkpoints |
|---|
| A | 1 | Measure | Measure | Measure |
| B | 3 | Measure | Measure | Measure |
| C | 5 | Measure | Measure | Measure |
Do not conclude that fewer steps are automatically better.
Durable steps provide fault-isolation, retry, and checkpoint boundaries.
The correct granularity depends on the workflow.
Cold Start Versus Replay
A durable workflow may resume after a wait or interruption.
For example:
Invocation 1
|
v
Step A
|
v
Checkpoint
|
v
Wait
|
v
Invocation ends
Invocation 2
|
v
Replay
|
v
Step B
|
v
Result
AWS describes this replay behavior as part of the durable execution model.
This means a benchmark should not label every resumed invocation simply as a "cold start."
Instead, classify events:
Initial Cold
Warm Continuation
Resume After Wait
Resume After Failure
New Execution Environment
These represent different performance scenarios.
Benchmark Durable Waits
A normal sleep keeps the invocation alive.
A durable wait does not.
AWS documents that durable wait suspends the function after checkpointing and resumes it later without consuming Lambda compute during the wait.
For example, conceptually:
await context.WaitAsync(
TimeSpan.FromMinutes(10));
The exact API should follow the version of the .NET SDK being used.
The important benchmark is:
Traditional sleep
vs
Durable wait
Measure:
Compute time
Resume latency
Total elapsed time
Do not compare only wall-clock duration.
A ten-minute workflow that spends ten minutes waiting is not equivalent to a ten-minute workflow consuming ten minutes of Lambda compute.
Benchmark External Service Calls
A realistic workflow may call:
Lambda
|
+--> DynamoDB
|
+--> S3
|
+--> HTTP API
|
+--> Payment Provider
External calls can dominate total latency.
Start with deterministic local computation:
No network
Then add:
DynamoDB
Then:
HTTP API
This lets you identify whether the observed latency comes from Lambda initialization or downstream dependencies.
Use Controlled External Latency
If you want to test workflow behavior under predictable conditions, use a controlled test dependency.
For example:
Test API
|
+--> 10 ms response
+--> 100 ms response
+--> 500 ms response
Then compare:
Workflow latency
vs
Dependency latency
This prevents a changing third-party service from contaminating the benchmark.
Benchmark Retries
Durable workflows support retry behavior for failed steps. AWS documents configurable retry strategies for durable steps.
A test can intentionally fail a step:
Attempt 1 -> Failure
Attempt 2 -> Failure
Attempt 3 -> Success
Measure:
Retry delay
Total workflow duration
Checkpoint behavior
Compute consumed
Final outcome
This is particularly important for workflows interacting with unreliable external services.
A retry benchmark should also verify that the business operation is safe to repeat according to the chosen execution semantics.
Test Idempotency
Durability does not automatically make an external side effect idempotent.
Consider:
ChargePayment()
If the operation is retried incorrectly, you could create duplicate business effects.
Prefer an idempotency key:
var request = new PaymentRequest
{
OrderId = orderId,
IdempotencyKey = executionId
};
The exact implementation depends on the external service.
The benchmark should verify:
Failure
|
v
Retry
|
v
Exactly one intended business effect
This is a functional correctness test as much as a performance test.
Measure Concurrency
Cold starts become more visible during bursts.
Run workloads such as:
1 request
10 requests
50 requests
100 requests
500 requests
These values are benchmark points, not claims about Lambda's capacity.
For each level, record:
Cold invocations
Warm invocations
p50 latency
p95 latency
p99 latency
Errors
Duration
A useful observation might look like:
Concurrency increases
|
v
More execution environments
|
v
More initialization events
|
v
Cold-start contribution increases
The actual relationship should be measured.
Use Percentiles Instead of Only Averages
Suppose your invocation durations are:
100 ms
110 ms
120 ms
130 ms
950 ms
The average is affected heavily by the outlier.
For latency-sensitive workloads, report:
p50
p90
p95
p99
For example:
| Metric | Value |
|---|
| p50 | Measure |
| p90 | Measure |
| p95 | Measure |
| p99 | Measure |
| Maximum | Measure |
This makes cold-start outliers easier to understand.
CloudWatch Measurements
Lambda exposes execution information through CloudWatch.
A practical measurement pipeline is:
Lambda
|
v
CloudWatch Logs
|
v
Metrics
|
v
Benchmark Dataset
|
v
Analysis
Capture:
Duration
Errors
Throttles
Invocations
Then correlate these with your own application measurements.
For durable workflows, also inspect durable execution information and checkpoint behavior. AWS documents monitoring durable executions through the Lambda console and CloudWatch Logs.
Add Application-Level Timing
Cloud metrics alone are not enough.
Instrument the handler:
var stopwatch = Stopwatch.StartNew();
logger.LogInformation(
"Workflow started at {Timestamp}",
DateTimeOffset.UtcNow);
// Business logic
stopwatch.Stop();
logger.LogInformation(
"Workflow completed in {ElapsedMs} ms",
stopwatch.Elapsed.TotalMilliseconds);
For production systems, structured logs are preferable to string-only messages.
Record a correlation identifier:
ExecutionId
WorkflowId
RequestId
StepName
This makes individual executions easier to reconstruct.
Avoid Timing Non-Deterministic Operations Outside Steps
Durable workflows replay code.
AWS specifically recommends wrapping non-deterministic operations inside durable steps. Examples include retrieving the current time, generating random identifiers, performing external API calls, and producing other side effects.
For example, avoid putting arbitrary external work directly into replayed orchestration logic.
Instead:
Durable Workflow
|
v
Durable Step
|
v
External API
The step's result can then be checkpointed and reused during replay.
This is important for both correctness and benchmark interpretation.
Benchmark Package and Initialization Optimization
For .NET Lambda, examine:
Package size
Dependency count
Reflection
JSON serialization
Static initialization
DI registration
AWS SDK clients
Configuration loading
AWS recommends source generators and Native AOT among the techniques that can improve .NET Lambda startup behavior.
A good optimization sequence is:
Baseline
|
v
Measure
|
v
Remove unnecessary initialization
|
v
Measure
|
v
Optimize serialization
|
v
Measure
|
v
Evaluate Native AOT / SnapStart
|
v
Measure Again
Do not optimize based on assumptions.
Durable SDK Versioning
The AWS Lambda Durable Execution SDK for .NET became generally available in July 2026. AWS's announcement states that the SDK is distributed through NuGet and includes local testing capabilities.
For production, pin the SDK version rather than allowing an uncontrolled dependency update.
This is particularly important for durable workflows because executions may span multiple invocations.
AWS recommends versioning and qualifying durable functions because durable executions require qualified function ARNs and because dependency/runtime changes can affect in-flight executions.
Production Deployment Considerations
Durable functions cannot simply be treated as ordinary Lambda functions.
AWS requires durable execution to be enabled when the function is created, and infrastructure-as-code deployments require the necessary checkpoint permissions. Durable functions also require qualified ARNs using a version or alias.
A production deployment should therefore include:
Source
|
v
Build
|
v
Test
|
v
Publish Version
|
v
Alias
|
v
Durable Function
Avoid relying on:
$LATEST
for production durable execution management.
Standard Lambda vs Durable Lambda
| Characteristic | Standard Lambda | Durable Lambda |
|---|
| Basic execution | Single invocation | Durable execution |
| Checkpointing | Application-managed | Built-in durable operations |
| Long waits | Invocation remains active | Function can suspend |
| State recovery | Application-managed | Checkpoint/replay |
| Retries | Application/service dependent | Durable step retry support |
| Replay | No orchestration replay model | Yes |
| Maximum workflow duration | Standard Lambda limits | Up to one year |
| Best suited for | Short event-driven work | Multi-step resilient workflows |
AWS documents durable functions as supporting workflows that can execute for up to one year, while standard Lambda functions remain subject to their normal execution model.
Durable Functions vs Step Functions
Durable Lambda does not replace every workflow engine.
AWS positions durable functions and Step Functions differently.
Durable functions are oriented toward application logic written inside Lambda, while Step Functions is designed for workflow orchestration across AWS services and provides a visual workflow model with extensive service integrations.
A practical decision looks like:
| Requirement | Durable Functions | Step Functions |
|---|
| Workflow logic primarily in code | Strong fit | Possible |
| Lambda-centric application | Strong fit | Possible |
| Visual workflow definition | Limited | Strong |
| Cross-service orchestration | Good | Strong |
| Fine-grained code-level control | Strong | Different model |
| Long-running workflows | Yes | Yes |
| Existing Step Functions estate | Migration may not be justified | Strong fit |
The benchmark should therefore evaluate the architecture against the application's requirements, not just raw latency.
A Practical Benchmark Harness
A simple C# benchmark runner can invoke a function repeatedly and capture elapsed time:
var stopwatch = Stopwatch.StartNew();
var response = await lambdaClient.InvokeAsync(
new InvokeRequest
{
FunctionName = functionName,
InvocationType = InvocationType.RequestResponse,
Payload = payload
});
stopwatch.Stop();
Console.WriteLine(
$"Status={response.StatusCode}, " +
$"Elapsed={stopwatch.Elapsed.TotalMilliseconds:F2} ms");
For a serious benchmark, extend this to record:
Iteration
Concurrency
Cold/Warm classification
Status
Duration
Payload size
Workflow ID
Error
Store the results as structured data rather than relying on console output.
Example Benchmark Dataset
Your final dataset might look like:
| Run | Type | Concurrency | Cold | Steps | Duration |
|---|
| 1 | Standard | 1 | Yes | N/A | Measure |
| 2 | Standard | 1 | No | N/A | Measure |
| 3 | Durable | 1 | Yes | 1 | Measure |
| 4 | Durable | 1 | No | 1 | Measure |
| 5 | Durable | 1 | Yes | 3 | Measure |
| 6 | Durable | 10 | Mixed | 3 | Measure |
Run enough iterations to reduce the influence of individual outliers.
Do not publish a benchmark from five requests and call it a production performance study.
Common Benchmarking Mistakes
Comparing Different Applications
If the standard Lambda and durable Lambda perform different work, the comparison is weak.
Measuring Only the First Request
One cold invocation does not represent normal workflow behavior.
Ignoring Replay
Durable workflows can resume and replay, so the complete execution lifecycle matters.
Using Real External Services Without Controls
Changing downstream latency can dominate the results.
Reporting Only Average Latency
Percentiles reveal outliers much better.
Changing Memory Between Tests
That changes CPU allocation and makes attribution difficult.
Mixing AOT, SnapStart, and JIT Without Labeling Them
These are different deployment configurations.
Ignoring Workflow Granularity
One large step and ten small steps have different checkpoint behavior.
Putting Side Effects Outside Durable Steps
Replay can cause unexpected behavior if non-deterministic or side-effecting operations are not modeled correctly.
Troubleshooting Unexpected Cold Starts
Warm Requests Are Still Slow
Check:
Static initialization
Dependency loading
Network initialization
Database clients
Configuration loading
Function memory
Downstream services
Cold Starts Increase During Bursts
Check concurrency and the number of new execution environments being created.
Also distinguish cold-start latency from downstream service latency.
Native AOT Does Not Improve the Result
Check:
AOT is an optimization, not a guarantee of a particular latency improvement.
Durable Workflow Takes Longer After a Wait
That is expected to some extent because resumption involves another invocation and replay.
Measure:
Wait completion
+
Resume scheduling
+
Initialization if needed
+
Replay
+
Remaining steps
AWS notes that actual resume timing can depend on system scheduling, Lambda cold-start behavior, and current system load.
Retry Causes Unexpected Duplicate Work
Check whether the operation is idempotent and whether side effects are correctly encapsulated within durable steps.
Best Practices
Benchmark standard and durable functions separately.
Measure cold and warm invocations independently.
Record p50, p95, and p99 latency.
Keep workload and configuration consistent between comparisons.
Measure initialization separately from business logic.
Test multiple memory configurations.
Evaluate deployment package size and initialization dependencies.
Benchmark Native AOT when appropriate for the .NET workload.
Evaluate SnapStart where supported by the selected configuration.
Measure workflow resume and replay behavior.
Test different durable-step granularities.
Keep external dependencies controlled during infrastructure benchmarks.
Make external side effects idempotent.
Use structured logging and execution correlation IDs.
Pin production SDK versions.
Deploy durable functions using qualified versions or aliases.
Repeat benchmarks under realistic concurrency.
Do not publish unsupported universal cold-start claims.
Conclusion
Durable Lambda changes the question developers should ask about serverless performance.
For a conventional Lambda function, the primary concern may be:
How fast can this request start and finish?
For a durable workflow, the question becomes:
How efficiently does this workflow move
through initialization, steps, checkpoints,
waits, retries, replay, and completion?
AWS Lambda's durable execution model provides checkpointing, replay, retries, waits, callbacks, parallel operations, and durable invocation while allowing workflows to run for up to one year.
The .NET SDK is now generally available, giving C# developers an idiomatic way to build these workflows.
But durable execution introduces additional dimensions that need to be measured.
A serious benchmark should therefore separate:
Cold Start
+
Application Initialization
+
Durable Checkpointing
+
Business Logic
+
External Services
+
Replay
+
Resume
Do not reduce all of that to a single latency number.
For production .NET workloads, benchmark the actual application, use controlled workloads, test realistic concurrency, compare deployment strategies, and measure both performance and correctness.
The most useful result is not:
"Durable Lambda adds X milliseconds."
It is:
"For this workload, this workflow structure, this .NET configuration, and this concurrency profile, cold starts represent this portion of total latency, while durable execution provides these reliability benefits."
That is a benchmark that can actually inform an architecture decision.
Frequently Asked Questions
What is a cold start in AWS Lambda?
A cold start occurs when Lambda creates and initializes a new execution environment before running the function. Initialization can include runtime startup, code loading, and application initialization.
Does a durable workflow eliminate cold starts?
No. Durable functions still use Lambda execution environments. A workflow can involve multiple invocations, and a resumed execution can require initialization depending on the execution environment lifecycle.
How long can a durable Lambda workflow run?
AWS currently documents durable workflows with execution durations of up to one year. Wait operations can suspend execution without consuming Lambda compute during the wait.
Does a durable wait consume Lambda compute?
No. A durable wait checkpoints the operation, suspends the function, and resumes it later when the wait completes.
Should I use Native AOT for .NET Lambda?
It is worth benchmarking when startup latency matters. AWS documents Native AOT as a way to reduce .NET Lambda cold-start work, but compatibility and application characteristics still need to be evaluated.
Should I use Step Functions instead of durable Lambda?
Not automatically. AWS positions durable functions as a code-centric workflow model inside Lambda, while Step Functions is a broader workflow orchestration service. The appropriate choice depends on the application's architecture and operational requirements.
What is the most important metric for this benchmark?
There is no single metric. For latency-sensitive applications, start with cold-start p50/p95/p99, warm latency, and total workflow duration. For durable workflows, also measure resume latency, replay behavior, retries, and checkpoint-related behavior.
Is the .NET Durable Execution SDK production-ready?
AWS announced general availability of the AWS Lambda Durable Execution SDK for .NET on July 23, 2026.