Simple Leave Management with AWS Lambda Durable Functions

Published: (January 13, 2026 at 07:17 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

Intro

In AWS re:Invent 2025, Lambda introduced Durable Functions with a great set of features.

Key highlights

  • A single execution can span up to one year.
  • Built‑in checkpointing tracks completed steps, so when an execution is retried after a resume or interruption, already‑finished steps are skipped and the workflow continues from the next step.

When it comes to orchestrating multiple AWS services into a workflow, AWS Step Functions has long been the go‑to choice. With Durable Functions, you can now achieve similar orchestration inside the familiar Lambda environment, which is fantastic!

In this blog post I explain how Durable Functions’ callback feature can be used to implement a human‑in‑the‑loop workflow.

Scenario Overview

When an execution starts, Durable Functions launch a Lambda invocation. For multi‑step executions you can:

  1. Pause (or wait) at a specific step for a given time period or until a signal is received from an external process.
  2. Upon receiving the external signal, the execution either resumes (on success) or terminates (on failure).

This native capability is perfect for business processes that require human approval.

Example: Leave Request Workflow

StepDescription
1Employee sends a leave request → Durable Function starts an execution.
2A leave record is created in a DynamoDB table with pending state.
3Employee receives an email confirming receipt of the request.
4Manager receives an email containing a callback ID to approve or reject the leave.
5Durable Function holds execution until the manager’s decision is received.
6Manager approves or rejects → execution resumes.
7If the manager does not act within the timeout, the request expires.
8Leave status is updated in DynamoDB.
9Employee receives an email with the manager’s decision or an expiry notice.

Architecture Details

1. Proxy Function

  • Purpose: Accept and validate the incoming leave‑request payload.
  • Implementation: Exposed via a Lambda Function URL.
  • Why needed?
    • Durable Functions’ synchronous invocations are limited to 15 minutes.
    • To run longer, we invoke the durable function asynchronously (InvocationType='Event'), i.e., fire‑and‑forget.

2. Durable Function Execution Flow

  1. Create leave record in DynamoDB.

  2. Send email to the employee confirming receipt.

  3. Send email to the manager with a callback ID and a link to approve/reject.

  4. Wait for callback (wait_for_callback step). Execution pauses here.

  5. Callback handling – a separate Lambda (exposed via Function URL) receives callback_id and decision.

    {
        "callback_id": "abc123-def456-ghi789",
        "decision": "approve"
    }
  6. The callback Lambda calls the new SDK methods:

    # Pseudo‑code
    lambda_client.send_durable_execution_callback_success(
        CallbackId=callback_id,
        Output={"status": "APPROVED"}
    )
    # or
    lambda_client.send_durable_execution_callback_failure(
        CallbackId=callback_id,
        ErrorMessage="Rejected by manager"
    )

    Note: These methods are not available in the default boto3 version shipped with Lambda. Package boto3 ≥ 1.42.1 with your function code.

  7. Upon receiving the callback, the durable execution restarts.

  8. If the manager does not respond within the timeout (e.g., 5 minutes), wait_for_callback raises a CallableRuntimeError with the message “Callback timed out.”

  9. The leave record is updated accordingly (approved, rejected, or expired).

  10. A final email is sent to the employee, and the execution completes.

Try This Yourself

A complete sample project (AWS CDK + Python) is available on GitHub:

🔗 Repository: https://github.com/pubudusj/simple-leave-management-with-durable-functions

Setup Steps

  1. Clone the repository

    git clone https://github.com/pubudusj/simple-leave-management-with-durable-functions.git
    cd simple-leave-management-with-durable-functions
  2. Configure environment variables

    cp .env.example .env
    # Edit .env and fill in the required values.
    # Ensure SYSTEM_FROM_EMAIL is verified in Amazon SES.
  3. Deploy the stack

    cdk deploy

    After deployment you will see two Lambda Function URLs in the output:

    • Create leave request endpoint
    • Process leave request (manager) endpoint

1. Create a Leave Request

curl -X POST \
     -H "Content-Type: application/json" \
     -d '{
           "start_date":"2026-01-10",
           "end_date":"2026-01-20",
           "employee_email":"employee@email.com"
         }' \
     <CREATE_LEAVE_REQUEST_URL>
  • Result
    • The employee receives a confirmation email.
    • The manager receives an email containing a callback ID and a link to approve or reject the request.

2. Manager Approves / Rejects

curl -X POST \
     -H "Content-Type: application/json" \
     -d '{
           "callback_id":"<CALLBACK_ID>",
           "decision":"approve"
         }' \
     <PROCESS_LEAVE_REQUEST_URL>
  • Result
    • The durable execution resumes, updates the DynamoDB record, and sends a final status email to the employee.

3. Timeout Scenario

If the manager does not act within the configured timeout (default 5 minutes for the demo), the leave request is automatically marked expired, and the employee receives an expiry notification.

Summary

  • Durable Functions now support long‑running, checkpointed workflows (up to one year).
  • The callback pattern enables human‑in‑the‑loop steps without external state machines.
  • Using a proxy Lambda allows asynchronous invocation, bypassing the 15‑minute synchronous limit.
  • The sample project demonstrates a complete end‑to‑end leave‑request flow with DynamoDB, SES, and Lambda callbacks.

Give it a try, and let me know how you extend this pattern to your own business processes!

OWS

Please try this and let me know your thoughts!

Back to Blog

Related posts

Read more »