Build resilient, long-running AWS Lambda functions that automatically checkpoint progress and resume after failures. Durable functions can run for up to one year while you pay only for active compute time.
- 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
Your durable function extends DurableHandler<I, O> and implements handleRequest(I input, DurableContext ctx). The DurableContext is your interface to durable operations:
ctx.step()– Execute code and checkpoint the resultctx.stepAsync()– Start a concurrent stepctx.wait()– Suspend execution without compute chargesctx.createCallback()– Wait for external events (approvals, webhooks)ctx.invoke()– Invoke another Lambda function and wait for the resultctx.invokeAsync()– Start a concurrent Lambda function invocationctx.runInChildContext()– Run an isolated child context with its own checkpoint logctx.runInChildContextAsync()– Start a concurrent child context
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java</artifactId>
<version>VERSION</version>
</dependency>public class OrderProcessor extends DurableHandler<Order, OrderResult> {
@Override
protected OrderResult handleRequest(Order order, DurableContext ctx) {
// Step 1: Validate and reserve inventory
var reservation = ctx.step("reserve-inventory", Reservation.class,
() -> inventoryService.reserve(order.getItems()));
// Step 2: Process payment
var payment = ctx.step("process-payment", Payment.class,
() -> paymentService.charge(order.getPaymentMethod(), order.getTotal()));
// Wait for warehouse processing (no compute charges)
ctx.wait(Duration.ofHours(2));
// Step 3: Confirm shipment
var shipment = ctx.step("confirm-shipment", Shipment.class,
() -> shippingService.ship(reservation, order.getAddress()));
return new OrderResult(order.getId(), shipment.getTrackingNumber());
}
}See examples/README.md for complete instructions on local testing and running cloud integration tests.
See Deploy and invoke Lambda durable functions with the AWS CLI for more information on deploying and invoking durable functions.
See Deploy Lambda durable functions with Infrastructure as Code for more information on deploying durable functions using infrastructure-as-code.
- AWS Documentation – Official AWS Lambda durable functions guide
- Best Practices – Patterns and recommendations
- SDK Design – Details of SDK internal architecture
Core Operations
- Steps – Execute code with automatic checkpointing and retry support
- Wait - Pause execution without blocking Lambda resources
- Callbacks - Wait for external systems to respond
- Invoke - Call other durable functions
- Child Contexts - Organize complex workflows into isolated units
Examples
- Examples - Working examples of each operation
Advanced Topics
- Configuration - Customize SDK behaviour
- Error Handling - SDK exceptions for handling failures
- Logging - How to use DurableLogger
- Testing - Utilities for local development and cloud-based integration testing
See CONTRIBUTING for information about reporting security issues.
This project is licensed under the Apache-2.0 License. See LICENSE for details.