Intro
In AWS re:Invent 2025, Lambda introduced Durable Functions with a great set of features. One of the main features is that a single execution can span up to one year. Also with built-in checkpointing it is possible to track the steps that were already completed and when an execution retried from a resume or an interruption, completed steps will be skipped and resumes from the next step.
When it comes to orchestrating multiple AWS services into a workflow, up until now, AWS Step Functions was the best choice. However, now Durable Functions too offer similar functionality to build a workflow within the same familiar Lambda environment, which is great!
In this blog post, I explain how Durable Function's callback feature can be used for a human-in-the-loop functionality.
Durable Function callbacks
When an execution starts, Durable Function will start an invocation. When there are multiple steps within the execution, it is possible to set the execution on hold (or wait) in a certain step for a given time period or until a signal is received from an external process. In case of a external signal, once the signal is received by the Lambda service, based on the success or failure nature of the signal, the execution that was on hold can be resumed or completely terminated.
This is a great feature supported natively by Durable Functions that is helpful for an example, in a business process where a human approval is required to continue with the flow.
Simple leave management with Durable Functions
In this example, an employee can send a leave request and the manager can approve or reject the request. Below are the steps involved and how Durable Function is being used.
- Employee sends a leave request. Durable function starts an execution.
- A Leave is created in a DynamoDB table with pending state.
- The employee receives an email with the request receipt confirmation.
- The manager receives an email with a callback id to be used to approve or reject the leave.
- Durable function keeps the execution on hold until manager approval or rejection is received.
- Once the manager approves or rejects, the execution resumes.
- If the manager didn’t process the request within a given time period, the request will be expired.
- The leave status is updated in the DynamoDB table.
- The employee receives an email with the manager’s decision or expiry.
How it works
- There is a proxy function which accepts and validates the incoming request to create a leave. Here I used a Lambda Function URL to submit the request.
-
Once validated, the proxy function will invoke the durable function.
Why use the proxy function?
Even with Durable functions, the synchronous invocations are limited by 15 minutes. Since I need the durable function to run longer, it is required to trigger the durable function asynchronously. Using the proxy function, durable function is invoked with invocation type ‘Event’, where it just fire-and-forget and will not wait for the durable function to complete.
When the durable function starts its execution, first a leave record is created in the DynamoDB table.
Then, an email is sent to the employee confirming the receipt of the leave request.
In the next step, an email is sent to the manager asking to approve or reject the leave request. This step is a callback step. The execution waits at this step until the manager approves or rejects.
Since this is a callback step, there is a callback id generated. This callback id is indicated in the email to the manager.
To simulate the manager’s approval or rejection, there is a Function URL exposed to trigger the Process Leave Lambda function.
This function accepts callback_id and the decision (approve or reject) as input.
-
Based on the decision, this function will call the boto3 methods of Lambda send_durable_execution_callback_success or send_durable_execution_callback_failure using the given callback id.
Please note: These latest SDK methods are not available with the boto3 version provided by Lambda by default as of now. So, it is required to package boto3 version 1.42.1 or newer with your Lambda source code.
When Lambda service receives the decision, the durable execution that was on hold will re-start.
If the manager’s decision was not received on time (I set this to 5 minutes at the moment), the wait_for_callback step will throw an CallableRuntimeError exception with an error message - Callback timed out.
Based on the decision or expiry of callback, the leave record in DB is updated.
Then an email will be sent to the employee with the leave's final status and the execution is completed.
Try this yourself
Here is a Github repository of a sample project I created with AWS CDK and Python for you to try out this scenario in your AWS account.
https://github.com/pubudusj/simple-leave-management-with-durable-functions
Clone the repository.
Copy the .env.example into .env and add the values. The value for SYSTEM_FROM_EMAIL should be already configured in Simple Email Service (SES) to send emails to the manager and employee email addresses.
Deploy the stack with CDK.
Once deployed, there will be two Lambda function urls in the output - one for creating the leave request and the other for process leave request (as manager).
-
Send a POST request to the create leaves endpoint with a payload similar to below:
{ "start_date":"2026-01-10", "end_date": "2026-01-20", "employee_email": "employee@email.com" } This will send an email to the employee email address as follows:

Also, an email to the manager with the callback id as follows:

-
Manager can send a POST request to the leave process endpoint with the callback id in the email with his decision (approve or reject) as follows:
{ "callback_id":"[callback id from email]", "decision": "approve" } Based on the decision, the employee will receive an email with the status.

If the manager didn't process the decision within given time (for demo purposes, this was set to 5 minutes), the leave will be marked as expired and employee will receive an email as follows:

Please try this and let me know your thoughts!
Resources
AWS Lambda Durable Functions documentation: https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html
Durable execution SDK: https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-sdk.html

Top comments (0)