Lambda durable functions SDK, Testing SDK and fully functional examples
See the codeBuild resilient, long-running AWS Lambda functions with automatic state persistence, retry logic, and workflow orchestration. Lambda durable functions can run for up to one year while maintaining reliable progress through checkpoints and automatic failure recovery.
This monorepo contains the following NPM packages:
| Package | Description | NPM |
|---|---|---|
| @aws/durable-execution-sdk-js | Core SDK for building durable Lambda functions | |
| @aws/durable-execution-sdk-js-testing | Testing utilities for local development and CI/CD | |
| @aws/durable-execution-sdk-js-eslint-plugin | ESLint rules for durable function best practices |
npm install @aws/durable-execution-sdk-js
import {
withDurableExecution,
DurableContext,
} from "@aws/durable-execution-sdk-js";
const handler = async (event: any, context: DurableContext) => {
// Use the context logger for structured logging
context.logger.info("Starting workflow", { userId: event.userId });
// Execute a durable step with automatic retry
const userData = await context.step("fetch-user", async (stepCtx) => {
// Step-scoped logger includes step metadata
stepCtx.logger.debug("Fetching user from database");
return fetchUserFromDB(event.userId);
});
// Wait for 5 seconds (no compute charges during wait)
await context.wait({ seconds: 5 });
// Process data in another step
const result = await context.step("process-user", async (stepCtx) => {
return processUser(userData);
});
context.logger.info("Workflow completed", { result });
return result;
};
export const lambdaHandler = withDurableExecution(handler);
Durable functions require a qualified identifier for invocation. You must specify a version or alias. Unqualified ARNs or function names without a suffix are not supported to ensure deterministic replay behavior.
The following example uses asynchronous invocation (--invocation-type Event), which queues the event and returns immediately, enabling executions that can run for up to one year:
aws lambda invoke \
--function-name my-durable-function:$LATEST \
--invocation-type Event \
--cli-binary-format raw-in-base64-out \
--payload '{"userId": "12345"}' \
response.json
[!TIP] To ensure idempotent execution, use the
--durable-execution-nameparameter. See Idempotency in the Lambda developer guide for additional information.
[!IMPORTANT] For production deployments, use numbered versions or aliases instead of
$LATESTfor deterministic replay behavior. See Invoking durable Lambda functions for more details.
The testing SDK enables local development and unit testing without deploying to AWS, as well as cloud testing against deployed Lambda functions:
npm install @aws/durable-execution-sdk-js-testing --save-dev
import { LocalDurableTestRunner } from "@aws/durable-execution-sdk-js-testing";
// Create runner with skipTime to fast-forward through waits
await LocalDurableTestRunner.setupTestEnvironment({ skipTime: true });
const runner = new LocalDurableTestRunner({
handlerFunction: myDurableHandler,
});
const result = await runner.run({ userId: "123" });
// Assert execution status
expect(result.getStatus()).toBe("SUCCEEDED");
expect(result.getResult()).toEqual({ processedUser: "..." });
// Assert number of Lambda invocations (initial+replay after wait)
expect(result.getInvocations().length).toBe(2);
// Assert operations executed
const operations = result.getOperations();
expect(operations.length).toBe(3); // 2 steps + 1 wait
// Inspect individual operations
const fetchStep = runner.getOperation("fetch-user");
expect(fetchStep.getStatus()).toBe("SUCCEEDED");
See the Testing SDK documentation for more details.
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
See CONTRIBUTING for information about reporting security issues.
This project is licensed under the Apache-2.0 License. See LICENSE for details.
Lambda durable functions SDK, Testing SDK and fully functional examples
See the codeBuild resilient, long-running AWS Lambda functions with automatic state persistence, retry logic, and workflow orchestration. Lambda durable functions can run for up to one year while maintaining reliable progress through checkpoints and automatic failure recovery.
This monorepo contains the following NPM packages:
| Package | Description | NPM |
|---|---|---|
| @aws/durable-execution-sdk-js | Core SDK for building durable Lambda functions | |
| @aws/durable-execution-sdk-js-testing | Testing utilities for local development and CI/CD | |
| @aws/durable-execution-sdk-js-eslint-plugin | ESLint rules for durable function best practices |
npm install @aws/durable-execution-sdk-js
import {
withDurableExecution,
DurableContext,
} from "@aws/durable-execution-sdk-js";
const handler = async (event: any, context: DurableContext) => {
// Use the context logger for structured logging
context.logger.info("Starting workflow", { userId: event.userId });
// Execute a durable step with automatic retry
const userData = await context.step("fetch-user", async (stepCtx) => {
// Step-scoped logger includes step metadata
stepCtx.logger.debug("Fetching user from database");
return fetchUserFromDB(event.userId);
});
// Wait for 5 seconds (no compute charges during wait)
await context.wait({ seconds: 5 });
// Process data in another step
const result = await context.step("process-user", async (stepCtx) => {
return processUser(userData);
});
context.logger.info("Workflow completed", { result });
return result;
};
export const lambdaHandler = withDurableExecution(handler);
Durable functions require a qualified identifier for invocation. You must specify a version or alias. Unqualified ARNs or function names without a suffix are not supported to ensure deterministic replay behavior.
The following example uses asynchronous invocation (--invocation-type Event), which queues the event and returns immediately, enabling executions that can run for up to one year:
aws lambda invoke \
--function-name my-durable-function:$LATEST \
--invocation-type Event \
--cli-binary-format raw-in-base64-out \
--payload '{"userId": "12345"}' \
response.json
[!TIP] To ensure idempotent execution, use the
--durable-execution-nameparameter. See Idempotency in the Lambda developer guide for additional information.
[!IMPORTANT] For production deployments, use numbered versions or aliases instead of
$LATESTfor deterministic replay behavior. See Invoking durable Lambda functions for more details.
The testing SDK enables local development and unit testing without deploying to AWS, as well as cloud testing against deployed Lambda functions:
npm install @aws/durable-execution-sdk-js-testing --save-dev
import { LocalDurableTestRunner } from "@aws/durable-execution-sdk-js-testing";
// Create runner with skipTime to fast-forward through waits
await LocalDurableTestRunner.setupTestEnvironment({ skipTime: true });
const runner = new LocalDurableTestRunner({
handlerFunction: myDurableHandler,
});
const result = await runner.run({ userId: "123" });
// Assert execution status
expect(result.getStatus()).toBe("SUCCEEDED");
expect(result.getResult()).toEqual({ processedUser: "..." });
// Assert number of Lambda invocations (initial+replay after wait)
expect(result.getInvocations().length).toBe(2);
// Assert operations executed
const operations = result.getOperations();
expect(operations.length).toBe(3); // 2 steps + 1 wait
// Inspect individual operations
const fetchStep = runner.getOperation("fetch-user");
expect(fetchStep.getStatus()).toBe("SUCCEEDED");
See the Testing SDK documentation for more details.
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
See CONTRIBUTING for information about reporting security issues.
This project is licensed under the Apache-2.0 License. See LICENSE for details.
56 followers · starred Dec 2025