

# Lambda runtimes
<a name="lambda-runtimes"></a>

Lambda supports multiple languages through the use of *runtimes*. A runtime provides a language-specific environment that relays invocation events, context information, and responses between Lambda and the function. You can use runtimes that Lambda provides, or build your own. 

Lambda is agnostic to your choice of runtime. For simple functions, interpreted languages like Python and Node.js offer the fastest performance. For functions with more complex computation, compiled languages like Java are often slower to initialize but run quickly in the Lambda handler. Choice of runtime is also influenced by developer preference and language familiarity.

Each major programming language release has a separate runtime, with a unique *runtime identifier*, such as `nodejs24.x` or `python3.14`. To configure a function to use a new major language version, you need to change the runtime identifier. Since AWS Lambda cannot guarantee backward compatibility between major versions, this is a customer-driven operation.

 For a [function defined as a container image](images-create.md), you choose a runtime and the Linux distribution when you create the container image. To change the runtime, you create a new container image.

When you use a .zip file archive for the deployment package, you choose a runtime when you create the function. To change the runtime, you can [update your function's configuration](configuration-function-zip.md). The runtime is paired with one of the Amazon Linux distributions. The underlying execution environment provides additional libraries and [environment variables](configuration-envvars.md) that you can access from your function code.

Lambda invokes your function in an [execution environment](lambda-runtime-environment.md). The execution environment provides a secure and isolated runtime environment that manages the resources required to run your function. Lambda re-uses the execution environment from a previous invocation if one is available, or it can create a new execution environment. 

To use other languages in Lambda, such as [Go](lambda-golang.md) or [Rust](lambda-rust.md), use an [OS-only runtime](runtimes-provided.md). The Lambda execution environment provides a [runtime interface](runtimes-api.md) for getting invocation events and sending responses. You can deploy other languages by implementing a [custom runtime](runtimes-custom.md) alongside your function code, or in a [layer](chapter-layers.md).

## Supported runtimes
<a name="runtimes-supported"></a>

The following table lists the supported Lambda runtimes and projected deprecation dates. After a runtime is deprecated, you're still able to create and update functions for a limited period. For more information, see [Runtime use after deprecation](#runtime-deprecation-levels). The table provides the currently forecasted dates for runtime deprecation, based on our [Runtime deprecation policy](#runtime-support-policy). These dates are provided for planning purposes and are subject to change.

**Important**  
Amazon Linux 2 is scheduled for end of life on June 30, 2026. Lambda runtimes and container base images for Java 8 (AL2), Java 11, Java 17, Python 3.10, Python 3.11, and provided.al2 will continue to receive patches for [critical and selected important](https://alas.aws.amazon.com/faqs.html) Amazon Linux 2 security issues, in addition to language runtime patches, until the deprecation dates shown in the table below.  
We recommend customers upgrade to an Amazon Linux 2023-based runtime as soon as possible. For customers upgrading to Java 21 or Java 25, you can use [AWS Transform custom](https://docs.aws.amazon.com/transform/latest/userguide/custom.html) to assist with these upgrades. For customers unable to upgrade their Java version, we plan to release Amazon Linux 2023-based runtimes for Java 8, Java 11, and Java 17 before the end of Q2 2026.


| Name | Identifier | Operating system | Deprecation date | Block function create | Block function update | 
| --- | --- | --- | --- | --- | --- | 
|  Node.js 24  |  `nodejs24.x`  |  Amazon Linux 2023  |   Apr 30, 2028   |   Jun 1, 2028   |   Jul 1, 2028   | 
|  Node.js 22  |  `nodejs22.x`  |  Amazon Linux 2023  |   Apr 30, 2027   |   Jun 1, 2027   |   Jul 1, 2027   | 
|  Node.js 20  |  `nodejs20.x`  |  Amazon Linux 2023  |   Apr 30, 2026   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  Python 3.14  |  `python3.14`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  Python 3.13  |  `python3.13`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  Python 3.12  |  `python3.12`  |  Amazon Linux 2023  |   Oct 31, 2028   |   Nov 30, 2028   |   Jan 10, 2029   | 
|  Python 3.11  |  `python3.11`  |  Amazon Linux 2  |   Jun 30, 2027   |   Jul 31, 2027   |   Aug 31, 2027   | 
|  Python 3.10  |  `python3.10`  |  Amazon Linux 2  |   Oct 31, 2026   |   Nov 30, 2026   |   Jan 15, 2027   | 
|  Java 25  |  `java25`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  Java 21  |  `java21`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  Java 17  |  `java17`  |  Amazon Linux 2  |   Jun 30, 2027   |   Jul 31, 2027   |   Aug 31, 2027   | 
|  Java 11  |  `java11`  |  Amazon Linux 2  |   Jun 30, 2027   |   Jul 31, 2027   |   Aug 31, 2027   | 
|  Java 8  |  `java8.al2`  |  Amazon Linux 2  |   Jun 30, 2027   |   Jul 31, 2027   |   Aug 31, 2027   | 
|  .NET 10  |  `dotnet10`  |  Amazon Linux 2023  |   Nov 14, 2028   |   Dec 14, 2028   |   Jan 15, 2029   | 
|  .NET 9 (container only)  |  `dotnet9`  |  Amazon Linux 2023  |   Nov 10, 2026   |   Not scheduled   |   Not scheduled   | 
|  .NET 8  |  `dotnet8`  |  Amazon Linux 2023  |   Nov 10, 2026   |   Dec 10, 2026   |   Jan 11, 2027   | 
|  Ruby 3.4  |  `ruby3.4`  |  Amazon Linux 2023  |   Mar 31, 2028   |   Apr 30, 2028   |   May 31, 2028   | 
|  Ruby 3.3  |  `ruby3.3`  |  Amazon Linux 2023  |   Mar 31, 2027   |   Apr 30, 2027   |   May 31, 2027   | 
|  Ruby 3.2  |  `ruby3.2`  |  Amazon Linux 2  |   Mar 31, 2026   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  OS-only Runtime  |  `provided.al2023`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  OS-only Runtime  |  `provided.al2`  |  Amazon Linux 2  |   Jul 31, 2026   |   Aug 31, 2026   |   Sep 30, 2026   | 

**Note**  
For new regions, Lambda will not support runtimes that are set to be deprecated within the next 6 months.

Lambda keeps managed runtimes and their corresponding container base images up to date with patches and support for minor version releases. For more information see [Lambda runtime updates](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html).

To programmatically interact with other AWS services and resources from your Lambda function, you can use one of AWS SDKs. The Node.js, Python, and Ruby runtimes include a version of the AWS SDK. However, to maintain full control of your dependencies, and to maximize [backward compatibility](runtimes-update.md#runtime-update-compatibility) during automatic runtime updates, we recommend that you always include the SDK modules your code uses (along with any dependencies) in your function's deployment package or in a [Lambda layer](chapter-layers.md).

We recommend that you use the runtime-included SDK version only when you can't include additional packages in your deployment. For example, when you create your function using the Lambda console code editor or using inline function code in an CloudFormation template.

Lambda periodically updates the versions of the AWS SDKs included in the Node.js, Python, and Ruby runtimes. To determine the version of the AWS SDK included in the runtime you're using, see the following sections:
+ [Runtime-included SDK versions (Node.js)](lambda-nodejs.md#nodejs-sdk-included)
+ [Runtime-included SDK versions (Python)](lambda-python.md#python-sdk-included)
+ [Runtime-included SDK versions (Ruby)](lambda-ruby.md#ruby-sdk-included)

Lambda continues to support the Go programming language after deprecation of the Go 1.x runtime. For more information, see [ Migrating AWS Lambda functions from the Go1.x runtime to the custom runtime on Amazon Linux 2](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/) on the *AWS Compute Blog*.

All supported Lambda runtimes support both x86\$164 and arm64 architectures.

## New runtime releases
<a name="runtimes-future"></a>

Lambda provides managed runtimes for new language versions only when the release reaches the long-term support (LTS) phase of the language's release cycle. For example, for the [Node.js release cycle](https://nodejs.org/en/about/previous-releases), when the release reaches the Active LTS phase.

Before the release reaches the long-term support phase, it remains in development and can still be subject to breaking changes. Lambda applies runtime updates automatically by default, so breaking changes to a runtime version could stop your functions from working as expected.

Lambda doesn't provide managed runtimes for language versions which aren't scheduled for LTS release.

The following list shows the target launch month for upcoming Lambda runtimes. These dates are indicative only and subject to change.
+ **Ruby 3.5** - March 2026
+ **Java 8, 11, and 17 on AL2023** - Q2 2026
+ **Node.js 26** - November 2026
+ **Python 3.15** - November 2026

## Runtime deprecation policy
<a name="runtime-support-policy"></a>

Lambda runtimes for .zip file archives are built around a combination of operating system, programming language, and software libraries that are subject to maintenance and security updates. Lambda’s standard deprecation policy is to deprecate a runtime when any major component of the runtime reaches the end of community long-term support (LTS) and security updates are no longer available. Most usually, this is the language runtime, though in some cases, a runtime can be deprecated because the operating system (OS) reaches end of LTS.

After a runtime is deprecated, AWS may no longer apply security patches or updates to that runtime, and functions using that runtime are no longer eligible for technical support. Such deprecated runtimes are provided ‘as-is’, without any warranties, and may contain bugs, errors, defects, or other vulnerabilities.

To learn more about managing runtime upgrades and deprecation, see the following sections and [Managing AWS Lambda runtime upgrades](https://aws.amazon.com/blogs/compute/managing-aws-lambda-runtime-upgrades/) on the *AWS Compute Blog*.

**Important**  
Lambda occasionally delays deprecation of a Lambda runtime for a limited period beyond the end of support date of the language version that the runtime supports. During this period, Lambda only applies security patches to the runtime OS. Lambda doesn’t apply security patches to programming language runtimes after they reach their end of support date.

## Shared responsibility model
<a name="runtimes-shared-responsibility"></a>

 Lambda is responsible for curating and publishing security updates for all supported managed runtimes and container base images. By default, Lambda will apply these updates automatically to functions using managed runtimes. Where the default automatic runtime update setting has been changed, see the [runtime management controls shared responsibility model](runtime-management-shared.md). For functions deployed using container images, you're responsible for rebuilding your function's container image from the latest base image and redeploying the container image. 

 When a runtime is deprecated, Lambda’s responsibility for updating the managed runtime and container base images ceases. You are responsible for upgrading your functions to use a supported runtime or base image. 

 In all cases, you are responsible for applying updates to your function code, including its dependencies. Your responsibilities under the shared responsibility model are summarized in the following table.


| Runtime lifecycle phase | Lambda's responsibilities | Your responsibilities | 
| --- | --- | --- | 
| Supported managed runtime |  Provide regular runtime updates with security patches and other updates. Apply runtime updates automatically by default (see [Runtime update modes](runtimes-update.md#runtime-management-controls) for non-default behaviors).  | Update your function code, including dependencies, to address any security vulnerabilities. | 
| Supported container image | Provide regular updates to container base image with security patches and other updates. |  Update your function code, including dependencies, to address any security vulnerabilities. Regularly re-build and re-deploy your container image using the latest base image.  | 
| Managed runtime approaching deprecation |  Notify customers prior to runtime deprecation via documentation, Health Dashboard, email, and Trusted Advisor. Responsibility for runtime updates ends at deprecation.  |  Monitor Lambda documentation, Health Dashboard, email, or Trusted Advisor for runtime deprecation information. Upgrade functions to a supported runtime before the previous runtime is deprecated.  | 
| Container image approaching deprecation |  Deprecation notifications are not available for functions using container images. Responsibility for container base image updates ends at deprecation.  | Be aware of deprecation schedules and upgrade functions to a supported base image before the previous image is deprecated. | 

## Runtime use after deprecation
<a name="runtime-deprecation-levels"></a>

After a runtime is deprecated, AWS may no longer apply security patches or updates to that runtime, and functions using that runtime are no longer eligible for technical support. While you can continue to invoke your functions indefinitely, AWS strongly recommends migrating to a supported runtime. Deprecated runtimes are provided 'as-is', without any warranties, and may contain bugs, errors, defects, or other vulnerabilities. Functions that use a deprecated runtime may also experience degraded performance or other issues, such as a certificate expiry, that can cause them to stop working properly.

You can update a function to use a newer supported runtime at any time after a runtime is deprecated. We recommend testing your function with the new runtime before applying changes in production environments. You will not be able to revert to the deprecated runtime after function updates are blocked. We recommend using function [versions](configuration-versions.md) and [aliases](configuration-aliases.md) to enable safe deployment with rollback.

The following timeline describes what happens when a runtime is deprecated:


| Runtime lifecycle phase | When | What | 
| --- | --- | --- | 
|  Deprecation notice period  |  At least 180 days before deprecation  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)  | 
|  Deprecation  |  Deprecation date  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)  | 
|  Block function create  |  At least 30 days after deprecation  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)  | 
|  Block function update  |  At least 60 days after deprecation  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)  | 

**Note**  
For some runtimes, AWS is delaying the block-function-create and block-function-update dates beyond the usual 30 and 60 days after deprecation. AWS has made this change in response to customer feedback to give you more time to upgrade your functions. Refer to the tables in [Supported runtimes](#runtimes-supported) and [Deprecated runtimes](#runtimes-deprecated) to see the dates for your runtime. Lambda will not start blocking function creates or updates before the dates given in these tables.

## Receiving runtime deprecation notifications
<a name="runtime-deprecation-notify"></a>

When a runtime approaches its deprecation date, Lambda sends you an email alert if any functions in your AWS account use that runtime. Notifications are also displayed in the Health Dashboard and in AWS Trusted Advisor.
+ Receiving email notifications:

  Lambda sends you an email alert at least **180 days** before a runtime is deprecated. This email lists the \$1LATEST versions of all functions using the runtime. To see a full list of affected function versions, use Trusted Advisor or see [Retrieve data about Lambda functions that use a deprecated runtime](runtimes-list-deprecated.md).

  Lambda sends email notification to your AWS account's primary account contact. For information about viewing or updating the email addresses in your account, see [Updating contact information](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-update-contact.html) in the *AWS General Reference*.
+ Receiving notifications through the Health Dashboard:

  The Health Dashboard displays a notification at least **180 days** before a runtime is deprecated. Notifications appear on the **Your account health** page under [Other notifications](https://health.aws.amazon.com/health/home#/account/dashboard/other-notifications). The **Affected resources** tab of the notification lists the \$1LATEST versions of all functions using the runtime.
**Note**  
To see a full and up-to-date list of affected function versions, use Trusted Advisor or see [Retrieve data about Lambda functions that use a deprecated runtime](runtimes-list-deprecated.md).

  Health Dashboard notifications expire 90 days after the affected runtime is deprecated.
+ Using AWS Trusted Advisor

  Trusted Advisor displays a notification at least **180 days** before a runtime is deprecated. Notifications appear on the [Security](https://console.aws.amazon.com/trustedadvisor/home#/category/security) page. A list of your affected functions is displayed under **AWS Lambda Functions Using Deprecated Runtimes**. This list of functions shows both \$1LATEST and published versions and updates automatically to reflect your functions' current status.

  You can turn on weekly email notifications from Trusted Advisor in the [Preferences](https://console.aws.amazon.com/trustedadvisor/home?#/preferences) page of the Trusted Advisor console.

## Deprecated runtimes
<a name="runtimes-deprecated"></a>

The following runtimes have reached end of support:


| Name | Identifier | Operating system | Deprecation date | Block function create | Block function update | 
| --- | --- | --- | --- | --- | --- | 
|  Python 3.9  |  python3.9  |  Amazon Linux 2  |   Dec 15, 2025   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  Node.js 18  |  nodejs18.x  |  Amazon Linux 2  |   Sep 1, 2025   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  .NET 6  |  dotnet6  |  Amazon Linux 2  |   Dec 20, 2024   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  Python 3.8  |  python3.8  |  Amazon Linux 2  |   Oct 14, 2024   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  Node.js 16  |  nodejs16.x  |  Amazon Linux 2  |   Jun 12, 2024   |   Aug 31, 2026   |   Sep 30, 2026   | 
|  .NET 7 (container only)  |  dotnet7  |  Amazon Linux 2  |   May 14, 2024   |   N/A   |   N/A   | 
|  Java 8  |  java8  |  Amazon Linux  |   Jan 8, 2024   |   Feb 8, 2024   |   Sep 30, 2026   | 
|  Go 1.x  |  go1.x  |  Amazon Linux  |   Jan 8, 2024   |   Feb 8, 2024   |   Sep 30, 2026   | 
|  OS-only Runtime  |  provided  |  Amazon Linux  |   Jan 8, 2024   |   Feb 8, 2024   |   Sep 30, 2026   | 
|  Ruby 2.7  |  ruby2.7  |  Amazon Linux 2  |   Dec 7, 2023   |   Jan 9, 2024   |   Sep 30, 2026   | 
|  Node.js 14  |  nodejs14.x  |  Amazon Linux 2  |   Dec 4, 2023   |   Jan 9, 2024   |   Sep 30, 2026   | 
|  Python 3.7  |  python3.7  |  Amazon Linux  |   Dec 4, 2023   |   Jan 9, 2024   |   Sep 30, 2026   | 
|  .NET Core 3.1  |  dotnetcore3.1  |  Amazon Linux 2  |   Apr 3, 2023   |   Apr 3, 2023   |   May 3, 2023   | 
|  Node.js 12  |  nodejs12.x  |  Amazon Linux 2  |   Mar 31, 2023   |   Mar 31, 2023   |   Apr 30, 2023   | 
|  Python 3.6  |  python3.6  |  Amazon Linux  |   Jul 18, 2022   |   Jul 18, 2022   |   Aug 29, 2022   | 
|  .NET 5 (container only)  |  dotnet5.0  |  Amazon Linux 2  |   May 10, 2022   |   N/A   |   N/A   | 
|  .NET Core 2.1  |  dotnetcore2.1  |  Amazon Linux  |   Jan 5, 2022   |   Jan 5, 2022   |   Apr 13, 2022   | 
|  Node.js 10  |  nodejs10.x  |  Amazon Linux 2  |   Jul 30, 2021   |   Jul 30, 2021   |   Feb 14, 2022   | 
|  Ruby 2.5  |  ruby2.5  |  Amazon Linux  |   Jul 30, 2021   |   Jul 30, 2021   |   Mar 31, 2022   | 
|  Python 2.7  |  python2.7  |  Amazon Linux  |   Jul 15, 2021   |   Jul 15, 2021   |   May 30, 2022   | 
|  Node.js 8.10  |  nodejs8.10  |  Amazon Linux  |   Mar 6, 2020   |   Feb 4, 2020   |   Mar 6, 2020   | 
|  Node.js 4.3  |  nodejs4.3  |  Amazon Linux  |   Mar 5, 2020   |   Feb 3, 2020   |   Mar 5, 2020   | 
|  Node.js 4.3 edge  |  nodejs4.3-edge  |  Amazon Linux  |   Mar 5, 2020   |   Mar 31, 2019   |   Apr 30, 2019   | 
|  Node.js 6.10  |  nodejs6.10  |  Amazon Linux  |   Aug 12, 2019   |   Jul 12, 2019   |   Aug 12, 2019   | 
|  .NET Core 1.0  |  dotnetcore1.0  |  Amazon Linux  |   Jun 27, 2019   |   Jun 30, 2019   |   Jul 30, 2019   | 
|  .NET Core 2.0  |  dotnetcore2.0  |  Amazon Linux  |   May 30, 2019   |   Apr 30, 2019   |   May 30, 2019   | 
|  Node.js 0.10  |  nodejs  |  Amazon Linux  |   Aug 30, 2016   |   Sep 30, 2016   |   Oct 31, 2016   | 

In almost all cases, the end-of-life date of a language version or operating system is known well in advance. The following links give end-of-life schedules for each language that Lambda supports as a managed runtime.

**Language and framework support policies**
+ **Node.js** – [github.com](https://github.com/nodejs/Release#release-schedule)
+ **Python** – [devguide.python.org](https://devguide.python.org/versions/#versions)
+ **Ruby** – [www.ruby-lang.org](https://www.ruby-lang.org/en/downloads/branches/)
+ **Java** – [www.oracle.com](https://www.oracle.com/java/technologies/java-se-support-roadmap.html) and [Corretto FAQs](https://aws.amazon.com/corretto/faqs/)
+ **Go** – [golang.org](https://golang.org/doc/devel/release.html)
+ **.NET** – [dotnet.microsoft.com](https://dotnet.microsoft.com/platform/support/policy/dotnet-core)

# Understanding how Lambda manages runtime version updates
<a name="runtimes-update"></a>

Lambda keeps each managed runtime up to date with security updates, bug fixes, new features, performance enhancements, and support for minor version releases. These runtime updates are published as *runtime versions*. Lambda applies runtime updates to functions by migrating the function from an earlier runtime version to a new runtime version.

By default, for functions using managed runtimes, Lambda applies runtime updates automatically. With automatic runtime updates, Lambda takes on the operational burden of patching the runtime versions. For most customers, automatic updates are the right choice. You can change this default behavior by [configuring runtime management settings](runtime-management-configure-settings.md).

Lambda also publishes each new runtime version as a container image. To update runtime versions for container-based functions, you must [create a new container image](images-create.md) from the updated base image and redeploy your function.

Each runtime version is associated with a version number and an ARN (Amazon Resource Name). Runtime version numbers use a numbering scheme that Lambda defines, independent of the version numbers that the programming language uses. Runtime version numbers are not always sequential. For example, version 42 might be followed by version 45. The runtime version ARN is a unique identifier for each runtime version. You can view the ARN of your function's current runtime version in the Lambda console, or the [`INIT_START` line of your function logs](runtime-management-identify.md).

Runtime versions should not be confused with runtime identifiers. Each runtime has a unique **runtime identifier**, such as `python3.14` or `nodejs24.x`. These correspond to each major programming language release. Runtime versions describe the patch version of an individual runtime.

**Note**  
The ARN for the same runtime version number can vary between AWS Regions and CPU architectures.

**Topics**
+ [

## Backward compatibility
](#runtime-update-compatibility)
+ [

## Runtime update modes
](#runtime-management-controls)
+ [

## Two-phase runtime version rollout
](#runtime-management-two-phase)
+ [

# Configuring Lambda runtime management settings
](runtime-management-configure-settings.md)
+ [

# Rolling back a Lambda runtime version
](runtime-management-rollback.md)
+ [

# Identifying Lambda runtime version changes
](runtime-management-identify.md)
+ [

# Understanding the shared responsibility model for Lambda runtime management
](runtime-management-shared.md)
+ [

# Controlling Lambda runtime update permissions for high-compliance applications
](runtime-management-hc-applications.md)

## Backward compatibility
<a name="runtime-update-compatibility"></a>

Lambda strives to provide runtime updates that are backward compatible with existing functions. However, as with software patching, there are rare cases in which a runtime update can negatively impact an existing function. For example, security patches can expose an underlying issue with an existing function that depends on the previous, insecure behavior.

When building and deploying your function, it is important to understand how to manage your dependencies to avoid potential incompatibilities with a future runtime update. For example, suppose your function has a dependency on package A, which in turn depends on package B. Both packages are included in the Lambda runtime (for example, they could be parts of the SDK or its dependencies, or parts of the runtime system libraries).

Consider the following scenarios:


| Deployment | Patching compatible | Reason | 
| --- | --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html)  | Yes | Future runtime updates to packages A and B are backward compatible. | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html)  | Yes | Your deployment takes precedence, so future runtime updates to packages A and B have no effect. | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html)  | Yes\$1 |  Future runtime updates to package B are backward compatible. \$1If A and B are tightly coupled, compatibility issues can occur. For example, the `boto3` and `botocore` packages in the AWS SDK for Python should be deployed together.  | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html)  | No | Future runtime updates to package A might require an updated version of package B. However, the deployed version of package B takes precedence, and might not be forward compatible with the updated version of package A. | 

To maintain compatibility with future runtime updates, follow these best practices:
+ **When possible, package all dependencies:** Include all required libraries, including the AWS SDK and its dependencies, in your deployment package. This ensures a stable, compatible set of components.
+ **Use runtime-provided SDKs sparingly:** Only rely on the runtime-provided SDK when you can't include additional packages (for example, when using the Lambda console code editor or inline code in an AWS CloudFormation template).
+ **Avoid overriding system libraries:** Don't deploy custom operating system libraries that may conflict with future runtime updates.

## Runtime update modes
<a name="runtime-management-controls"></a>

Lambda strives to provide runtime updates that are backward compatible with existing functions. However, as with software patching, there are rare cases in which a runtime update can negatively impact an existing function. For example, security patches can expose an underlying issue with an existing function that depends on the previous, insecure behavior. Lambda runtime management controls help reduce the risk of impact to your workloads in the rare event of a runtime version incompatibility. For each [function version](configuration-versions.md) (`$LATEST` or published version), you can choose one of the following runtime update modes:
+ **Auto (default)** – Automatically update to the most recent and secure runtime version using [Two-phase runtime version rollout](#runtime-management-two-phase). We recommend this mode for most customers so that you always benefit from runtime updates.
+ **Function update** – Update to the most recent and secure runtime version when you update your function. When you update your function, Lambda updates the runtime of your function to the most recent and secure runtime version. This approach synchronizes runtime updates with function deployments, giving you control over when Lambda applies runtime updates. With this mode, you can detect and mitigate rare runtime update incompatibilities early. When using this mode, you must regularly update your functions to keep their runtime up to date.
+ **Manual** – Manually update your runtime version. You specify a runtime version in your function configuration. The function uses this runtime version indefinitely. In the rare case in which a new runtime version is incompatible with an existing function, you can use this mode to roll back your function to an earlier runtime version. We recommend against using **Manual** mode to try to achieve runtime consistency across deployments. For more information, see [Rolling back a Lambda runtime version](runtime-management-rollback.md).

Responsibility for applying runtime updates to your functions varies according to which runtime update mode you choose. For more information, see [Understanding the shared responsibility model for Lambda runtime management](runtime-management-shared.md).

## Two-phase runtime version rollout
<a name="runtime-management-two-phase"></a>

Lambda introduces new runtime versions in the following order:

1. In the first phase, Lambda applies the new runtime version whenever you create or update a function. A function gets updated when you call the [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html) or [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html) API operations.

1. In the second phase, Lambda updates any function that uses the **Auto** runtime update mode and that hasn't already been updated to the new runtime version. 

The overall duration of the rollout process varies according to multiple factors, including the severity of any security patches included in the runtime update.

If you're actively developing and deploying your functions, you will most likely pick up new runtime versions during the first phase. This synchronizes runtime updates with function updates. In the rare event that the latest runtime version negatively impacts your application, this approach lets you take prompt corrective action. Functions that aren't in active development still receive the operational benefit of automatic runtime updates during the second phase.

This approach doesn't affect functions set to **Function update** or **Manual** mode. Functions using **Function update** mode receive the latest runtime updates only when you create or update them. Functions using **Manual** mode don't receive runtime updates.

Lambda publishes new runtime versions in a gradual, rolling fashion across AWS Regions. If your functions are set to **Auto** or **Function update** modes, it's possible that functions deployed at the same time to different Regions, or at different times in the same Region, will pick up different runtime versions. Customers who require guaranteed runtime version consistency across their environments should [use container images to deploy their Lambda functions](images-create.md). The **Manual** mode is designed as a temporary mitigation to enable runtime version rollback in the rare event that a runtime version is incompatible with your function.

# Configuring Lambda runtime management settings
<a name="runtime-management-configure-settings"></a>

You can configure runtime management settings using the Lambda console or the AWS Command Line Interface (AWS CLI).

**Note**  
You can configure runtime management settings separately for each [function version](configuration-versions.md).

**To configure how Lambda updates your runtime version (console)**

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) of the Lambda console.

1. Choose the name of a function.

1. On the **Code** tab, under **Runtime settings**, choose **Edit runtime management configuration**.

1. Under **Runtime management configuration**, choose one of the following:
   + To have your function update to the latest runtime version automatically, choose **Auto**.
   + To have your function update to the latest runtime version when you change the function, choose **Function update**.
   + To have your function update to the latest runtime version only when you change the runtime version ARN, choose **Manual**. You can find the runtime version ARN under **Runtime management configuration**. You can also find the ARN in the `INIT_START` line of your function logs.

   For more information about these options, see [Runtime update modes](runtimes-update.md#runtime-management-controls).

1. Choose **Save**.

**To configure how Lambda updates your runtime version (AWS CLI)**

To configure runtime management for a function, run the [put-runtime-management-config](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/put-runtime-management-config.html) AWS CLI command. When using `Manual` mode, you must also provide the runtime version ARN.

```
aws lambda put-runtime-management-config \
  --function-name my-function \
  --update-runtime-on Manual \
  --runtime-version-arn arn:aws:lambda:us-east-2::runtime:8eeff65f6809a3ce81507fe733fe09b835899b99481ba22fd75b5a7338290ec1
```

You should see output similar to the following:

```
{
  "UpdateRuntimeOn": "Manual",
  "FunctionArn": "arn:aws:lambda:us-east-2:111122223333:function:my-function",
  "RuntimeVersionArn": "arn:aws:lambda:us-east-2::runtime:8eeff65f6809a3ce81507fe733fe09b835899b99481ba22fd75b5a7338290ec1"
}
```

# Rolling back a Lambda runtime version
<a name="runtime-management-rollback"></a>

In the rare event that a new runtime version is incompatible with your existing function, you can roll back its runtime version to an earlier one. This keeps your application working and minimizes disruption, providing time to remedy the incompatibility before returning to the latest runtime version.

Lambda doesn't impose a time limit on how long you can use any particular runtime version. However, we strongly recommend updating to the latest runtime version as soon as possible to benefit from the latest security patches, performance improvements, and features. Lambda provides the option to roll back to an earlier runtime version only as a temporary mitigation in the rare event of a runtime update compatibility issue. Functions using an earlier runtime version for an extended period may eventually experience degraded performance or issues, such as a certificate expiry, which can cause them to stop working properly.

You can roll back a runtime version in the following ways:
+ [Using the Manual runtime update mode](#runtime-management-rollback-manual)
+ [Using published function versions](#runtime-management-rollback-published)

For more information, see [Introducing AWS Lambda runtime management controls](https://aws.amazon.com/blogs/compute/introducing-aws-lambda-runtime-management-controls/) on the AWS Compute Blog.

## Roll back a runtime version using Manual runtime update mode
<a name="runtime-management-rollback-manual"></a>

If you're using the **Auto** runtime version update mode, or you're using the `$LATEST` runtime version, you can roll back your runtime version using the **Manual** mode. For the [function version](configuration-versions.md) you want to roll back, change the runtime version update mode to **Manual** and specify the ARN of the previous runtime version. For more information about finding the ARN of the previous runtime version, see [Identifying Lambda runtime version changes](runtime-management-identify.md).

**Note**  
If the `$LATEST` version of your function is configured to use **Manual** mode, then you can't change the CPU architecture or runtime version that your function uses. To make these changes, you must change to **Auto** or **Function update** mode.

## Roll back a runtime version using published function versions
<a name="runtime-management-rollback-published"></a>

Published [function versions](configuration-versions.md) are an immutable snapshot of the `$LATEST` function code and configuration at the time that you created them. In **Auto** mode, Lambda automatically updates the runtime version of published function versions during phase two of the runtime version rollout. In **Function update** mode, Lambda doesn't update the runtime version of published function versions.

Published function versions using **Function update** mode therefore create a static snapshot of the function code, configuration, and runtime version. By using **Function update** mode with function versions, you can synchronize runtime updates with your deployments. You can also coordinate rollback of code, configuration, and runtime versions by redirecting traffic to an earlier published function version. You can integrate this approach into your continuous integration and continuous delivery (CI/CD) for fully automatic rollback in the rare event of runtime update incompatibility. When using this approach, you must update your function regularly and publish new function versions to pick up the latest runtime updates. For more information, see [Understanding the shared responsibility model for Lambda runtime management](runtime-management-shared.md).

# Identifying Lambda runtime version changes
<a name="runtime-management-identify"></a>

The [runtime version number](runtimes-update.md) and ARN are logged in the `INIT_START` log line, which Lambda emits to CloudWatch Logs each time that it creates a new [execution environment](concepts-basics.md#gettingstarted-concepts-runtime). Because the execution environment uses the same runtime version for all function invocations, Lambda emits the `INIT_START` log line only when Lambda executes the init phase. Lambda doesn't emit this log line for each function invocation. Lambda emits the log line to CloudWatch Logs, but it is not visible in the console. 

**Note**  
Runtime version numbers are not always sequential. For example, version 42 might be followed by version 45.

**Example INIT\$1START log line**  

```
INIT_START Runtime Version: python:3.13.v14    Runtime Version ARN: arn:aws:lambda:eu-south-1::runtime:7b620fc2e66107a1046b140b9d320295811af3ad5d4c6a011fad1fa65127e9e6I
```

Rather than working directly with the logs, you can use [Amazon CloudWatch Contributor Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContributorInsights-CreateRule.html) to identify transitions between runtime versions. The following rule counts the distinct runtime versions from each `INIT_START` log line. To use the rule, replace the example log group name `/aws/lambda/*` with the appropriate prefix for your function or group of functions.

```
{
  "Schema": {
    "Name": "CloudWatchLogRule",
    "Version": 1
  },
  "AggregateOn": "Count",
  "Contribution": {
    "Filters": [
      {
        "Match": "eventType",
        "In": [
          "INIT_START"
        ]
      }
    ],
    "Keys": [
      "runtimeVersion",
      "runtimeVersionArn"
    ]
  },
  "LogFormat": "CLF",
  "LogGroupNames": [
    "/aws/lambda/*"
  ],
  "Fields": {
    "1": "eventType",
    "4": "runtimeVersion",
    "8": "runtimeVersionArn"
  }
}
```

The following CloudWatch Contributor Insights report shows an example of a runtime version transition as captured by the preceding rule. The orange line shows execution environment initialization for the earlier runtime version (**python:3.13.v12**), and the blue line shows execution environment initialization for the new runtime version (**python:3.13.v14**).

![\[\]](http://docs.aws.amazon.com/lambda/latest/dg/images/runtime_version_graph.png)


# Understanding the shared responsibility model for Lambda runtime management
<a name="runtime-management-shared"></a>

Lambda is responsible for curating and publishing security updates for all supported managed runtimes and container images. Responsibility for updating existing functions to use the latest runtime version varies depending on which runtime update mode you use.

Lambda is responsible for applying runtime updates to all functions configured to use the **Auto** runtime update mode.

For functions configured with the **Function update** runtime update mode, you're responsible for regularly updating your function. Lambda is responsible for applying runtime updates when you make those updates. If you don't update your function, then Lambda doesn't update the runtime. If you don't regularly update your function, then we strongly recommend configuring it for automatic runtime updates so that it continues to receive security updates.

For functions configured to use the **Manual** runtime update mode, you're responsible for updating your function to use the latest runtime version. We strongly recommend that you use this mode only to roll back the runtime version as a temporary mitigation in the rare event of runtime update incompatibility. We also recommend that you change to **Auto** mode as quickly as possible to minimize the time in which your functions aren't patched.

If you're [using container images to deploy your functions](images-create.md), then Lambda is responsible for publishing updated base images. In this case, you're responsible for rebuilding your function's container image from the latest base image and redeploying the container image.

This is summarized in the following table:


****  

| Deployment mode | Lambda's responsibility | Customer's responsibility | 
| --- | --- | --- | 
| Managed runtime, Auto mode |  Publish new runtime versions containing the latest patches. Apply runtime patches to existing functions.  | Roll back to a previous runtime version in the rare event of a runtime update compatibility issue. Follow best practices for [backward compatibility](runtimes-update.md#runtime-update-compatibility). | 
| Managed runtime, Function update mode | Publish new runtime versions containing the latest patches. |  Update functions regularly to pick up the latest runtime version. Switch a function to **Auto** mode when you're not regularly updating the function. Roll back to a previous runtime version in the rare event of a runtime update compatibility issue. Follow best practices for [backward compatibility](runtimes-update.md#runtime-update-compatibility).  | 
| Managed runtime, Manual mode | Publish new runtime versions containing the latest patches. |  Use this mode only for temporary runtime rollback in the rare event of a runtime update compatibility issue. Switch functions to **Auto** or **Function update** mode and the latest runtime version as soon as possible.  | 
| Container image | Publish new container images containing the latest patches. | Redeploy functions regularly using the latest container base image to pick up the latest patches. | 

For more information about shared responsibility with AWS, see [Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/).

# Controlling Lambda runtime update permissions for high-compliance applications
<a name="runtime-management-hc-applications"></a>

To meet patching requirements, Lambda customers typically rely on automatic runtime updates. If your application is subject to strict patching freshness requirements, you may want to limit use of earlier runtime versions. You can restrict Lambda's runtime management controls by using AWS Identity and Access Management (IAM) to deny users in your AWS account access to the [PutRuntimeManagementConfig](https://docs.aws.amazon.com/lambda/latest/api/API_PutRuntimeManagementConfig.html) API operation. This operation is used to choose the runtime update mode for a function. Denying access to this operation causes all functions to default to the **Auto** mode. You can apply this restriction across your organization by using a [service control policies (SCP)](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html). If you must roll back a function to an earlier runtime version, you can grant a policy exception on a case-by-case basis.

# Retrieve data about Lambda functions that use a deprecated runtime
<a name="runtimes-list-deprecated"></a>

When a Lambda runtime is approaching deprecation, Lambda alerts you through email and provides notifications in the Health Dashboard and Trusted Advisor. These emails and notifications list the \$1LATEST versions of functions using the runtime. To list all of your function versions that use a particular runtime, you can use the AWS Command Line Interface (AWS CLI) or one of the AWS SDKs.

If you have a large number of functions which use a runtime that is due to be deprecated, you can also use the AWS CLI or AWS SDKs to help you prioritize updates to your most commonly invoked functions.

Refer to the following sections to learn how to use the AWS CLI and AWS SDKs to gather data about functions that use a particular runtime.

## Listing function versions that use a particular runtime
<a name="runtimes-list-deprecated-versions"></a>

To use the AWS CLI to list all of your function versions that use a particular runtime, run the following command. Replace `RUNTIME_IDENTIFIER` with the name of the runtime that’s being deprecated and choose your own AWS Region. To list only \$1LATEST function versions, omit `--function-version ALL` from the command.

```
aws lambda list-functions --function-version ALL --region us-east-1 --output text --query "Functions[?Runtime=='RUNTIME_IDENTIFIER'].FunctionArn" 
```

**Tip**  
The example command lists functions in the `us-east-1` region for a particular AWS account You’ll need to repeat this command for each region in which your account has functions and for each of your AWS accounts.

You can also list functions that use a particular runtime using one of the AWS SDKs. The following example code uses the V3 AWS SDK for JavaScript and the AWS SDK for Python (Boto3) to return a list of the function ARNs for functions using a particular runtime. The example code also returns the CloudWatch log group for each of the listed functions. You can use this log group to find the last invocation date for the function. See the following section [Identifying most commonly and most recently invoked functions](#runtimes-list-deprecated-statistics) for more information.

------
#### [ Node.js ]

**Example JavaScript code to list functions using a particular runtime**  

```
import { LambdaClient, ListFunctionsCommand } from "@aws-sdk/client-lambda";
const lambdaClient = new LambdaClient();

const command = new ListFunctionsCommand({
    FunctionVersion: "ALL",
    MaxItems: 50
});
const response = await lambdaClient.send(command);

for (const f of response.Functions){
    if (f.Runtime == '<your_runtime>'){ // Use the runtime id, e.g. 'nodejs24.x' or 'python3.14'
        console.log(f.FunctionArn);
        // get the CloudWatch log group of the function to
        // use later for finding the last invocation date
        console.log(f.LoggingConfig.LogGroup);
    }   
}
// If your account has more functions than the specified
// MaxItems, use the returned pagination token in the 
// next request with the 'Marker' parameter
if ('NextMarker' in response){
    let paginationToken = response.NextMarker;
  }
```

------
#### [ Python ]

**Example Python code to list functions using a particular runtime**  

```
import boto3
from botocore.exceptions import ClientError

def list_lambda_functions(target_runtime):

    lambda_client = boto3.client('lambda')
    
    response = lambda_client.list_functions(
        FunctionVersion='ALL',
        MaxItems=50
    )
    if not response['Functions']:
            print("No Lambda functions found")
    else: 
        for function in response['Functions']:   
            if function['PackageType']=='Zip' and function['Runtime'] == target_runtime: 
                print(function['FunctionArn'])
                # Print the CloudWatch log group of the function
                # to use later for finding last invocation date
                print(function['LoggingConfig']['LogGroup'])

    if 'NextMarker' in response:
       pagination_token = response['NextMarker']

if __name__ == "__main__":
    # Replace python3.12 with the appropriate runtime ID for your Lambda functions
    list_lambda_functions('python3.12')
```

------

To learn more about using an AWS SDK to list your functions using the [ListFunctions](https://docs.aws.amazon.com/lambda/latest/api/API_ListFunctions.html) action, see the [SDK documentation](https://aws.amazon.com/developer/tools/) for your preferred programming language.

You can also use the AWS Config Advanced queries feature to list all your functions that use an affected runtime. This query only returns function \$1LATEST versions, but you can aggregate queries to list function across all regions and multiple AWS accounts with a single command. To learn more, see [Querying the Current Configuration State of AWS Auto Scaling Resources](https://docs.aws.amazon.com/config/latest/developerguide/querying-AWS-resources.html) in the *AWS Config Developer Guide*.

## Identifying most commonly and most recently invoked functions
<a name="runtimes-list-deprecated-statistics"></a>

If your AWS account contains functions that use a runtime that's due to be deprecated, you might want to prioritize updating functions that are frequently invoked or functions that have been invoked recently.

If you have only a few functions, you can use the CloudWatch Logs console to gather this information by looking at your functions' log streams. See [View log data sent to CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#ViewingLogData) for more information.

To see the number of recent function invocations, you can also use the CloudWatch metrics information shown in the Lambda console. To view this information, do the following:

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) of the Lambda console.

1. Select the function you want to see invocation statistics for.

1. Choose the **Monitor** tab.

1. Set the time period you wish to view statistics for using the date range picker. Recent invocations are displayed in the **Invocations** pane.

For accounts with larger numbers of functions, it can be more efficient to gather this data programmatically using the AWS CLI or one of the AWS SDKs using the [DescribeLogStreams](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html) and [GetMetricStatistics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html) API actions.

The following examples provide code snippets using the V3 AWS SDK for JavaScript and the AWS SDK for Python (Boto3) to identify the last invoke date for a particular function and to determine the number of invocations for a particular function in the last 14 days.

------
#### [ Node.js ]

**Example JavaScript code to find last invocation time for a function**  

```
import { CloudWatchLogsClient, DescribeLogStreamsCommand } from "@aws-sdk/client-cloudwatch-logs";
const cloudWatchLogsClient = new CloudWatchLogsClient();
const command = new DescribeLogStreamsCommand({
    logGroupName: '<your_log_group_name>',
    orderBy: 'LastEventTime',
    descending: true,
    limit: 1
});
try {
    const response = await cloudWatchLogsClient.send(command);
    const lastEventTimestamp = response.logStreams.length > 0 ? 
        response.logStreams[0].lastEventTimestamp : null;
    // Convert the UNIX timestamp to a human-readable format for display
    const date = new Date(lastEventTimestamp).toLocaleDateString();
    const time = new Date(lastEventTimestamp).toLocaleTimeString();
    console.log(`${date} ${time}`);
    
} catch (e){
    console.error('Log group not found.')
}
```

------
#### [ Python ]

**Example Python code to find last invocation time for a function**  

```
import boto3
from datetime import datetime

cloudwatch_logs_client  = boto3.client('logs')

response = cloudwatch_logs_client.describe_log_streams(
    logGroupName='<your_log_group_name>',
    orderBy='LastEventTime',
    descending=True,
    limit=1
)

try:
    if len(response['logStreams']) > 0:
        last_event_timestamp = response['logStreams'][0]['lastEventTimestamp']
        print(datetime.fromtimestamp(last_event_timestamp/1000)) # Convert timestamp from ms to seconds
    else:
        last_event_timestamp = None
except:
    print('Log group not found')
```

------

**Tip**  
You can find your function's log group name using the [ListFunctions](https://docs.aws.amazon.com/lambda/latest/api/API_ListFunctions.html) API operation. See the code in [Listing function versions that use a particular runtime](#runtimes-list-deprecated-versions) for an example of how to do this.

------
#### [ Node.js ]

**Example JavaScript code to find number of invocations in last 14 days**  

```
import { CloudWatchClient, GetMetricStatisticsCommand } from "@aws-sdk/client-cloudwatch";
const cloudWatchClient = new CloudWatchClient();
const command = new GetMetricStatisticsCommand({
    Namespace: 'AWS/Lambda',
    MetricName: 'Invocations',
    StartTime: new Date(Date.now()-86400*1000*14), // 14 days ago
    EndTime: new Date(Date.now()),
    Period: 86400 * 14, // 14 days.
    Statistics: ['Sum'],
    Dimensions: [{
        Name: 'FunctionName',
        Value: '<your_function_name>'
    }]
});
const response = await cloudWatchClient.send(command);
const invokesInLast14Days = response.Datapoints.length > 0 ? 
    response.Datapoints[0].Sum : 0;

console.log('Number of invocations: ' + invokesInLast14Days);
```

------
#### [ Python ]

**Example Python code to find number of invocations in last 14 days**  

```
import boto3
from datetime import datetime, timedelta

cloudwatch_client = boto3.client('cloudwatch')

response = cloudwatch_client.get_metric_statistics(
    Namespace='AWS/Lambda',
    MetricName='Invocations',
    Dimensions=[
        {
            'Name': 'FunctionName',
            'Value': '<your_function_name>'
        },
    ],
    StartTime=datetime.now() - timedelta(days=14),
    EndTime=datetime.now(),
    Period=86400 * 14, # 14 days
    Statistics=[
        'Sum'
    ]
)

if len(response['Datapoints']) > 0:
    invokes_in_last_14_days = int(response['Datapoints'][0]['Sum'])
else:
    invokes_in_last_14_days = 0

print(f'Number of invocations: {invokes_in_last_14_days}')
```

------

# Modifying the runtime environment
<a name="runtimes-modify"></a>

You can use [internal extensions](lambda-extensions.md) to modify the runtime process. Internal extensions are not separate processes—they run as part of the runtime process.

Lambda provides language-specific [environment variables](configuration-envvars.md) that you can set to add options and tools to the runtime. Lambda also provides [wrapper scripts](#runtime-wrapper), which allow Lambda to delegate the runtime startup to your script. You can create a wrapper script to customize the runtime startup behavior.

## Language-specific environment variables
<a name="runtimes-envvars"></a>

Lambda supports configuration-only ways to enable code to be pre-loaded during function initialization through the following language-specific environment variables:
+ `JAVA_TOOL_OPTIONS` – On Java, Lambda supports this environment variable to set additional command-line variables in Lambda. This environment variable allows you to specify the initialization of tools, specifically the launching of native or Java programming language agents using the `agentlib` or `javaagent` options. For more information, see [`JAVA_TOOL_OPTIONS` environment variable](https://docs.aws.amazon.com/lambda/latest/dg/java-customization.html#java-tool-options).
+ `NODE_OPTIONS` – Available in [Node.js runtimes](lambda-nodejs.md).
+ `DOTNET_STARTUP_HOOKS` – On .NET Core 3.1 and above, this environment variable specifies a path to an assembly (dll) that Lambda can use.

Using language-specific environment variables is the preferred way to set startup properties.

## Wrapper scripts
<a name="runtime-wrapper"></a>

You can create a *wrapper script* to customize the runtime startup behavior of your Lambda function. A wrapper script enables you to set configuration parameters that cannot be set through language-specific environment variables.

**Note**  
Invocations may fail if the wrapper script does not successfully start the runtime process.

Wrapper scripts are supported on all native [Lambda runtimes](lambda-runtimes.md). Wrapper scripts are not supported on [OS-only runtimes](runtimes-provided.md) (the `provided` runtime family).

When you use a wrapper script for your function, Lambda starts the runtime using your script. Lambda sends to your script the path to the interpreter and all of the original arguments for the standard runtime startup. Your script can extend or transform the startup behavior of the program. For example, the script can inject and alter arguments, set environment variables, or capture metrics, errors, and other diagnostic information.

You specify the script by setting the value of the `AWS_LAMBDA_EXEC_WRAPPER` environment variable as the file system path of an executable binary or script.

### Example: Create and use a wrapper script as a Lambda layer
<a name="runtime-wrapper-example"></a>

In the following example, you create a wrapper script to start the Python interpreter with the `-X importtime` option. When you run the function, Lambda generates a log entry to show the duration of the import time for each import.

**To create and use a wrapper script as a layer**

1. Create a directory for the layer:

   ```
   mkdir -p python-wrapper-layer/bin
   cd python-wrapper-layer/bin
   ```

1. In the `bin` directory, paste the following code into a new file named `importtime_wrapper`. This is the wrapper script.

   ```
   #!/bin/bash
   
   # the path to the interpreter and all of the originally intended arguments
   args=("$@")
   
   # the extra options to pass to the interpreter
   extra_args=("-X" "importtime")
   
   # insert the extra options
   args=("${args[@]:0:$#-1}" "${extra_args[@]}" "${args[@]: -1}")
   
   # start the runtime with the extra options
   exec "${args[@]}"
   ```

1. Give the script executable permissions:

   ```
   chmod +x importtime_wrapper
   ```

1. Create a .zip file for the layer:

   ```
   cd ..
   zip -r ../python-wrapper-layer.zip .
   ```

1. Confirm that your .zip file has the following directory structure:

   ```
   python-wrapper-layer.zip
   └ bin
       └ importtime_wrapper
   ```

1. [Create a layer](creating-deleting-layers.md#layers-create) using the .zip package.

1. Create a function using the Lambda console.

   1. Open the [Lambda console](https://console.aws.amazon.com/lambda).

   1. Choose **Create function**.

   1. Enter a **Function name**.

   1. For **Runtime**, choose the **Latest supported** Python runtime.

   1. Choose **Create function**.

1. Add the layer to your function.

   1. Choose your function, and then choose the **Code** tab if it's not already selected.

   1. Scroll down to the **Layers** section, and then choose **Add a layer**.

   1. For **Layer source**, select **Custom layers**, and then choose your layer from the **Custom layers** dropdown list.

   1.  For **Version**, choose **1**.

   1. Choose **Add**.

1. Add the wrapper environment variable.

   1. Choose the **Configuration** tab, then choose **Environment variables**.

   1. Under **Environment variables**, choose **Edit**.

   1. Choose **Add environment variable**.

   1. For **Key**, enter `AWS_LAMBDA_EXEC_WRAPPER`.

   1. For **Value**, enter `/opt/bin/importtime_wrapper` (`/opt/` \$1 your .zip layer's folder structure).

   1. Choose **Save**.

1. Test the wrapper script.

   1. Choose the **Test** tab.

   1. Under **Test event**, choose **Test**. You don't need to create a test event—the default event will work.

   1. Scroll down to **Log output**. Because your wrapper script started the Python interpreter with the `-X importtime` option, the logs show the time required for each import. For example:

      ```
      532 |           collections
      import time:        63 |         63 |           _functools
      import time:      1053 |       3646 |         functools
      import time:      2163 |       7499 |       enum
      import time:       100 |        100 |         _sre
      import time:       446 |        446 |           re._constants
      import time:       691 |       1136 |         re._parser
      import time:       378 |        378 |         re._casefix
      import time:       670 |       2283 |       re._compiler
      import time:       416 |        416 |       copyreg
      ```

# Using the Lambda runtime API for custom runtimes
<a name="runtimes-api"></a>

AWS Lambda provides an HTTP API for [custom runtimes](runtimes-custom.md) to receive invocation events from Lambda and send response data back within the Lambda [execution environment](lambda-runtimes.md). This section contains the API reference for the Lambda runtime API.

**Lambda Managed Instances support concurrent requests**  
Lambda Managed Instances use the same runtime API as Lambda (default) functions. The key difference is that Managed Instances can accept concurrent `/next` and `/response` requests up to the configured `AWS_LAMBDA_MAX_CONCURRENCY` limit. This enables multiple invocations to be processed simultaneously within a single execution environment. For more information about Managed Instances, see [Understanding the Lambda Managed Instances execution environment](lambda-managed-instances-execution-environment.md).

![\[Architecture diagram of the execution environment.\]](http://docs.aws.amazon.com/lambda/latest/dg/images/telemetry-api-concept-diagram.png)


The OpenAPI specification for the runtime API version **2018-06-01** is available in [runtime-api.zip](samples/runtime-api.zip)

To create an API request URL, runtimes get the API endpoint from the `AWS_LAMBDA_RUNTIME_API` environment variable, add the API version, and add the desired resource path.

**Example Request**  

```
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next"
```

**Topics**
+ [

## Next invocation
](#runtimes-api-next)
+ [

## Invocation response
](#runtimes-api-response)
+ [

## Initialization error
](#runtimes-api-initerror)
+ [

## Invocation error
](#runtimes-api-invokeerror)

## Next invocation
<a name="runtimes-api-next"></a>

**Path** – `/runtime/invocation/next`

**Method** – **GET**

The runtime sends this message to Lambda to request an invocation event. The response body contains the payload from the invocation, which is a JSON document that contains event data from the function trigger. The response headers contain additional data about the invocation.

**Response headers**
+ `Lambda-Runtime-Aws-Request-Id` – The request ID, which identifies the request that triggered the function invocation.

  For example, `8476a536-e9f4-11e8-9739-2dfe598c3fcd`.
+ `Lambda-Runtime-Deadline-Ms` – The date that the function times out in Unix time milliseconds. 

  For example, `1542409706888`.
+ `Lambda-Runtime-Invoked-Function-Arn` – The ARN of the Lambda function, version, or alias that's specified in the invocation. 

  For example, `arn:aws:lambda:us-east-2:123456789012:function:custom-runtime`.
+ `Lambda-Runtime-Trace-Id` – The [AWS X-Ray tracing header](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader). 

  For example, `Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1`.
+ `Lambda-Runtime-Client-Context` – For invocations from the AWS Mobile SDK, data about the client application and device.
+ `Lambda-Runtime-Cognito-Identity` – For invocations from the AWS Mobile SDK, data about the Amazon Cognito identity provider.

Do not set a timeout on the `GET` request as the response may be delayed. Between when Lambda bootstraps the runtime and when the runtime has an event to return, the runtime process may be frozen for several seconds.

The request ID tracks the invocation within Lambda. Use it to specify the invocation when you send the response.

The tracing header contains the trace ID, parent ID, and sampling decision. If the request is sampled, the request was sampled by Lambda or an upstream service. The runtime should set the `_X_AMZN_TRACE_ID` with the value of the header. The X-Ray SDK reads this to get the IDs and determine whether to trace the request.

## Invocation response
<a name="runtimes-api-response"></a>

**Path** – `/runtime/invocation/AwsRequestId/response`

**Method** – **POST**

After the function has run to completion, the runtime sends an invocation response to Lambda. For synchronous invocations, Lambda sends the response to the client.

**Example success request**  

```
REQUEST_ID=156cb537-e2d4-11e8-9b34-d36013741fb9
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "SUCCESS"
```

## Initialization error
<a name="runtimes-api-initerror"></a>

If the function returns an error or the runtime encounters an error during initialization, the runtime uses this method to report the error to Lambda.

**Path** – `/runtime/init/error`

**Method** – **POST**

**Headers**

`Lambda-Runtime-Function-Error-Type` – Error type that the runtime encountered. Required: no. 

This header consists of a string value. Lambda accepts any string, but we recommend a format of <category.reason>. For example:
+ Runtime.NoSuchHandler
+ Runtime.APIKeyNotFound
+ Runtime.ConfigInvalid
+ Runtime.UnknownReason

**Body parameters**

`ErrorRequest` – Information about the error. Required: no. 

This field is a JSON object with the following structure:

```
{
      errorMessage: string (text description of the error),
      errorType: string,
      stackTrace: array of strings
}
```

Note that Lambda accepts any value for `errorType`.

The following example shows a Lambda function error message in which the function could not parse the event data provided in the invocation.

**Example Function error**  

```
{
      "errorMessage" : "Error parsing event data.",
      "errorType" : "InvalidEventDataException",
      "stackTrace": [ ]
}
```

**Response body parameters**
+ `StatusResponse` – String. Status information, sent with 202 response codes. 
+ `ErrorResponse` – Additional error information, sent with the error response codes. ErrorResponse contains an error type and an error message.

**Response codes**
+ 202 – Accepted
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Runtime should exit promptly.

**Example initialization error request**  

```
ERROR="{\"errorMessage\" : \"Failed to load function.\", \"errorType\" : \"InvalidFunctionException\"}"
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/init/error" -d "$ERROR" --header "Lambda-Runtime-Function-Error-Type: Unhandled"
```

## Invocation error
<a name="runtimes-api-invokeerror"></a>

If the function returns an error or the runtime encounters an error, the runtime uses this method to report the error to Lambda.

**Path** – `/runtime/invocation/AwsRequestId/error`

**Method** – **POST**

**Headers**

`Lambda-Runtime-Function-Error-Type` – Error type that the runtime encountered. Required: no. 

This header consists of a string value. Lambda accepts any string, but we recommend a format of <category.reason>. For example:
+ Runtime.NoSuchHandler
+ Runtime.APIKeyNotFound
+ Runtime.ConfigInvalid
+ Runtime.UnknownReason

**Body parameters**

`ErrorRequest` – Information about the error. Required: no. 

This field is a JSON object with the following structure:

```
{
      errorMessage: string (text description of the error),
      errorType: string,
      stackTrace: array of strings
}
```

Note that Lambda accepts any value for `errorType`.

The following example shows a Lambda function error message in which the function could not parse the event data provided in the invocation.

**Example Function error**  

```
{
      "errorMessage" : "Error parsing event data.",
      "errorType" : "InvalidEventDataException",
      "stackTrace": [ ]
}
```

**Response body parameters**
+ `StatusResponse` – String. Status information, sent with 202 response codes. 
+ `ErrorResponse` – Additional error information, sent with the error response codes. ErrorResponse contains an error type and an error message.

**Response codes**
+ 202 – Accepted
+ 400 – Bad Request
+ 403 – Forbidden
+ 500 – Container error. Non-recoverable state. Runtime should exit promptly.

**Example error request**  

```
REQUEST_ID=156cb537-e2d4-11e8-9b34-d36013741fb9
ERROR="{\"errorMessage\" : \"Error parsing event data.\", \"errorType\" : \"InvalidEventDataException\"}"
curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/error" -d "$ERROR" --header "Lambda-Runtime-Function-Error-Type: Unhandled"
```

# When to use Lambda's OS-only runtimes
<a name="runtimes-provided"></a>

Lambda provides [managed runtimes](lambda-runtimes.md) for Java, Python, Node.js, .NET, and Ruby. To create Lambda functions in a programming language that is not available as a managed runtime, use an OS-only runtime (the `provided` runtime family). There are three primary use cases for OS-only runtimes:
+ **Native ahead-of-time (AOT) compilation**: Languages such as Go, Rust, Swift, and C\$1\$1 compile natively to an executable binary, which doesn't require a dedicated language runtime. These languages only need an OS environment in which the compiled binary can run. You can also use Lambda OS-only runtimes to deploy binaries compiled with .NET Native AOT and Java GraalVM Native Image.

  You must include a runtime interface client in your binary. The runtime interface client calls the [Using the Lambda runtime API for custom runtimes](runtimes-api.md) to retrieve function invocations and then calls your function handler. Lambda provides runtime interface clients for [Rust](lambda-rust.md), [Go](golang-package.md#golang-package-mac-linux), [.NET Native AOT](dotnet-native-aot.md), [Swift](https://github.com/awslabs/swift-aws-lambda-runtime) (experimental), and [C\$1\$1](https://github.com/awslabs/aws-lambda-cpp) (experimental).

  You must compile your binary for a Linux environment and for the same instruction set architecture that you plan to use for the function (x86\$164 or arm64).
+ **Third-party runtimes**: You can run Lambda functions using off-the-shelf runtimes such as [Bref](https://bref.sh/docs/news/01-bref-1.0.html#amazon-linux-2) for PHP.
+ **Custom runtimes**: You can build your own runtime for a language or language version that Lambda doesn't provide a managed runtime for, such as Node.js 19. For more information, see [Building a custom runtime for AWS Lambda](runtimes-custom.md). This is the least common use case for OS-only runtimes.

Lambda supports the following OS-only runtimes:


| Name | Identifier | Operating system | Deprecation date | Block function create | Block function update | 
| --- | --- | --- | --- | --- | --- | 
|  OS-only Runtime  |  `provided.al2023`  |  Amazon Linux 2023  |   Jun 30, 2029   |   Jul 31, 2029   |   Aug 31, 2029   | 
|  OS-only Runtime  |  `provided.al2`  |  Amazon Linux 2  |   Jul 31, 2026   |   Aug 31, 2026   |   Sep 30, 2026   | 

The Amazon Linux 2023 (`provided.al2023`) runtime provides several advantages over Amazon Linux 2, including a smaller deployment footprint and updated versions of libraries such as `glibc`.

The `provided.al2023` runtime uses `dnf` as the package manager instead of `yum`, which is the default package manager in Amazon Linux 2. For more information about the differences between `provided.al2023` and `provided.al2`, see [Introducing the Amazon Linux 2023 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/) on the AWS Compute Blog.

# Building a custom runtime for AWS Lambda
<a name="runtimes-custom"></a>

You can implement an AWS Lambda runtime in any programming language. A runtime is a program that runs a Lambda function's handler method when the function is invoked. You can include the runtime in your function's deployment package or distribute it in a [layer](chapter-layers.md). When you create the Lambda function, choose an [OS-only runtime](runtimes-provided.md) (the `provided` runtime family).

**Note**  
Creating a custom runtime is an advanced use case. If you're looking for information about compiling to a native binary or using a third-party off-the-shelf runtime, see [When to use Lambda's OS-only runtimes](runtimes-provided.md).

For a walkthrough of the custom runtime deployment process, see [Tutorial: Building a custom runtime](runtimes-walkthrough.md).

**Topics**
+ [

## Requirements
](#runtimes-custom-build)
+ [

## Implementing response streaming in a custom runtime
](#runtimes-custom-response-streaming)
+ [

## Building custom runtimes for Lambda Managed Instances
](#runtimes-custom-managed-instances)

## Requirements
<a name="runtimes-custom-build"></a>

Custom runtimes must complete certain initialization and processing tasks. A runtime runs the function's setup code, reads the handler name from an environment variable, and reads invocation events from the Lambda runtime API. The runtime passes the event data to the function handler, and posts the response from the handler back to Lambda.

### Initialization tasks
<a name="runtimes-custom-initialization"></a>

The initialization tasks run once [per instance of the function](lambda-runtime-environment.md) to prepare the environment to handle invocations.
+ **Retrieve settings** – Read environment variables to get details about the function and environment.
  + `_HANDLER` – The location to the handler, from the function's configuration. The standard format is `file.method`, where `file` is the name of the file without an extension, and `method` is the name of a method or function that's defined in the file.
  + `LAMBDA_TASK_ROOT` – The directory that contains the function code.
  + `AWS_LAMBDA_RUNTIME_API` – The host and port of the runtime API.

  For a full list of available variables, see [Defined runtime environment variables](configuration-envvars.md#configuration-envvars-runtime).
+ **Initialize the function** – Load the handler file and run any global or static code that it contains. Functions should create static resources like SDK clients and database connections once, and reuse them for multiple invocations.
+ **Handle errors** – If an error occurs, call the [initialization error](runtimes-api.md#runtimes-api-initerror) API and exit immediately.

Initialization counts towards billed execution time and timeout. When an execution triggers the initialization of a new instance of your function, you can see the initialization time in the logs and [AWS X-Ray trace](services-xray.md).

**Example log**  

```
REPORT RequestId: f8ac1208... Init Duration: 48.26 ms   Duration: 237.17 ms   Billed Duration: 300 ms   Memory Size: 128 MB   Max Memory Used: 26 MB
```

### Processing tasks
<a name="runtimes-custom-processing"></a>

While it runs, a runtime uses the [Lambda runtime interface](runtimes-api.md) to manage incoming events and report errors. After completing initialization tasks, the runtime processes incoming events in a loop. In your runtime code, perform the following steps in order.
+ **Get an event** – Call the [next invocation](runtimes-api.md#runtimes-api-next) API to get the next event. The response body contains the event data. Response headers contain the request ID and other information.
+ **Propagate the tracing header** – Get the X-Ray tracing header from the `Lambda-Runtime-Trace-Id` header in the API response. Set the `_X_AMZN_TRACE_ID` environment variable locally with the same value. The X-Ray SDK uses this value to connect trace data between services.
+ **Create a context object** – Create an object with context information from environment variables and headers in the API response.
+ **Invoke the function handler** – Pass the event and context object to the handler.
+ **Handle the response** – Call the [invocation response](runtimes-api.md#runtimes-api-response) API to post the response from the handler.
+ **Handle errors** – If an error occurs, call the [invocation error](runtimes-api.md#runtimes-api-invokeerror) API.
+ **Cleanup** – Release unused resources, send data to other services, or perform additional tasks before getting the next event.

### Entrypoint
<a name="runtimes-custom-bootstrap"></a>

A custom runtime's entry point is an executable file named `bootstrap`. The bootstrap file can be the runtime, or it can invoke another file that creates the runtime. If the root of your deployment package doesn't contain a file named `bootstrap`, Lambda looks for the file in the function's layers. If the `bootstrap` file doesn't exist or isn't executable, your function returns a `Runtime.InvalidEntrypoint` error upon invocation.

Here's an example `bootstrap` file that uses a bundled version of Node.js to run a JavaScript runtime in a separate file named `runtime.js`.

**Example bootstrap**  

```
#!/bin/sh
    cd $LAMBDA_TASK_ROOT
    ./node-v11.1.0-linux-x64/bin/node runtime.js
```

## Implementing response streaming in a custom runtime
<a name="runtimes-custom-response-streaming"></a>

For [response streaming functions](configuration-response-streaming.md), the `response` and `error` endpoints have slightly modified behavior that lets the runtime stream partial responses to the client and return payloads in chunks. For more information about the specific behavior, see the following:
+ `/runtime/invocation/AwsRequestId/response` – Propagates the `Content-Type` header from the runtime to send to the client. Lambda returns the response payload in chunks via HTTP/1.1 chunked transfer encoding. To stream the response to Lambda, the runtime must:
  + Set the `Lambda-Runtime-Function-Response-Mode` HTTP header to `streaming`.
  + Set the `Transfer-Encoding` header to `chunked`.
  + Write the response conforming to the HTTP/1.1 chunked transfer encoding specification.
  + Close the underlying connection after it has successfully written the response.
+ `/runtime/invocation/AwsRequestId/error` – The runtime can use this endpoint to report function or runtime errors to Lambda, which also accepts the `Transfer-Encoding` header. This endpoint can only be called before the runtime begins sending an invocation response.
+ Report midstream errors using error trailers in `/runtime/invocation/AwsRequestId/response` – To report errors that occur after the runtime starts writing the invocation response, the runtime can optionally attach HTTP trailing headers named `Lambda-Runtime-Function-Error-Type` and `Lambda-Runtime-Function-Error-Body`. Lambda treats this as a successful response and forwards the error metadata that the runtime provides to the client. 
**Note**  
To attach trailing headers, the runtime must set the `Trailer` header value at the beginning of the HTTP request. This is a requirement of the HTTP/1.1 chunked transfer encoding specification.
  + `Lambda-Runtime-Function-Error-Type` – The error type that the runtime encountered. This header consists of a string value. Lambda accepts any string, but we recommend a format of *<category.reason>*. For example, `Runtime.APIKeyNotFound`.
  + `Lambda-Runtime-Function-Error-Body` – Base64-encoded information about the error.

## Building custom runtimes for Lambda Managed Instances
<a name="runtimes-custom-managed-instances"></a>

Lambda Managed Instances use the same runtime API as Lambda (default) functions. However, there are key differences in how custom runtimes must be implemented to support the concurrent execution model of Managed Instances.

### Concurrent request handling
<a name="runtimes-custom-managed-instances-concurrency"></a>

The primary difference when building custom runtimes for Managed Instances is support for concurrent invocations. Unlike Lambda (default) functions where the runtime processes one invocation at a time, Managed Instances can process multiple invocations simultaneously within a single execution environment.

Your custom runtime must:
+ **Support concurrent `/next` requests** – The runtime can make multiple simultaneous calls to the [next invocation](runtimes-api.md#runtimes-api-next) API, up to the limit specified by the `AWS_LAMBDA_MAX_CONCURRENCY` environment variable.
+ **Handle concurrent `/response` requests** – Multiple invocations can call the [invocation response](runtimes-api.md#runtimes-api-response) API simultaneously.
+ **Implement thread-safe request handling** – Ensure that concurrent invocations don't interfere with each other by properly managing shared resources and state.
+ **Use unique request IDs** – Track each invocation separately using the `Lambda-Runtime-Aws-Request-Id` header to match responses with their corresponding requests.

### Implementation pattern
<a name="runtimes-custom-managed-instances-implementation"></a>

A typical implementation pattern for Managed Instances runtimes involves creating worker threads or processes to handle concurrent invocations:

1. **Read the concurrency limit** – At initialization, read the `AWS_LAMBDA_MAX_CONCURRENCY` environment variable to determine how many concurrent invocations to support.

1. **Create worker pool** – Initialize a pool of workers (threads, processes, or async tasks) equal to the concurrency limit.

1. **Worker processing loop** – Each worker independently:
   + Calls `/runtime/invocation/next` to get an invocation event
   + Invokes the function handler with the event data
   + Posts the response to `/runtime/invocation/AwsRequestId/response`
   + Repeats the loop

### Additional considerations
<a name="runtimes-custom-managed-instances-considerations"></a>
+ **Logging format** – Managed Instances only support JSON log format. Ensure your runtime respects the `AWS_LAMBDA_LOG_FORMAT` environment variable and only uses JSON format. For more information, see [Configuring JSON and plain text log formats](monitoring-cloudwatchlogs-logformat.md).
+ **Shared resources** – Be cautious when using shared resources like the `/tmp` directory with concurrent invocations. Implement proper locking mechanisms to prevent race conditions.

For more information about Lambda Managed Instances execution environments, see [Understanding the Lambda Managed Instances execution environment](lambda-managed-instances-execution-environment.md).

# Tutorial: Building a custom runtime
<a name="runtimes-walkthrough"></a>

In this tutorial, you create a Lambda function with a custom runtime. You start by including the runtime in the function's deployment package. Then you migrate it to a layer that you manage independently from the function. Finally, you share the runtime layer with the world by updating its resource-based permissions policy.

## Prerequisites
<a name="runtimes-walkthrough-prereqs"></a>

This tutorial assumes that you have some knowledge of basic Lambda operations and the Lambda console. If you haven't already, follow the instructions in [Create a Lambda function with the console](getting-started.md#getting-started-create-function) to create your first Lambda function.

To complete the following steps, you need the [AWS CLI version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). Commands and the expected output are listed in separate blocks:

```
aws --version
```

You should see the following output:

```
aws-cli/2.13.27 Python/3.11.6 Linux/4.14.328-248.540.amzn2.x86_64 exe/x86_64.amzn.2
```

For long commands, an escape character (`\`) is used to split a command over multiple lines.

On Linux and macOS, use your preferred shell and package manager.

**Note**  
In Windows, some Bash CLI commands that you commonly use with Lambda (such as `zip`) are not supported by the operating system's built-in terminals. To get a Windows-integrated version of Ubuntu and Bash, [install the Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Example CLI commands in this guide use Linux formatting. Commands which include inline JSON documents must be reformatted if you are using the Windows CLI. 

You need an IAM role to create a Lambda function. The role needs permission to send logs to CloudWatch Logs and access the AWS services that your function uses. If you don't have a role for function development, create one now.

**To create an execution role**

1. Open the [roles page](https://console.aws.amazon.com/iam/home#/roles) in the IAM console.

1. Choose **Create role**.

1. Create a role with the following properties.
   + **Trusted entity** – **Lambda**.
   + **Permissions** – **AWSLambdaBasicExecutionRole**.
   + **Role name** – **lambda-role**.

   The **AWSLambdaBasicExecutionRole** policy has the permissions that the function needs to write logs to CloudWatch Logs.

## Create a function
<a name="runtimes-walkthrough-function"></a>

Create a Lambda function with a custom runtime. This example includes two files: a runtime `bootstrap` file and a function handler. Both are implemented in Bash.

1. Create a directory for the project, and then switch to that directory.

   ```
   mkdir runtime-tutorial
   cd runtime-tutorial
   ```

1. Create a new file called `bootstrap`. This is the custom runtime.  
**Example bootstrap**  

   ```
   #!/bin/sh
   
   set -euo pipefail
   
   # Initialization - load function handler
   source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
   
   # Processing
   while true
   do
     HEADERS="$(mktemp)"
     # Get an event. The HTTP request will block until one is received
     EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
   
     # Extract request ID by scraping response headers received above
     REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
   
     # Run the handler function from the script
     RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
   
     # Send the response
     curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
   done
   ```

   The runtime loads a function script from the deployment package. It uses two variables to locate the script. `LAMBDA_TASK_ROOT` tells it where the package was extracted, and `_HANDLER` includes the name of the script.

   After the runtime loads the function script, it uses the runtime API to retrieve an invocation event from Lambda, passes the event to the handler, and posts the response back to Lambda. To get the request ID, the runtime saves the headers from the API response to a temporary file, and reads the `Lambda-Runtime-Aws-Request-Id` header from the file.
**Note**  
Runtimes have additional responsibilities, including error handling, and providing context information to the handler. For details, see [Requirements](runtimes-custom.md#runtimes-custom-build).

1. Create a script for the function. The following example script defines a handler function that takes event data, logs it to `stderr`, and returns it.  
**Example function.sh**  

   ```
   function handler () {
     EVENT_DATA=$1
     echo "$EVENT_DATA" 1>&2;
     RESPONSE="Echoing request: '$EVENT_DATA'"
   
     echo $RESPONSE
   }
   ```

   The `runtime-tutorial` directory should now look like this:

   ```
   runtime-tutorial
   ├ bootstrap
   └ function.sh
   ```

1. Make the files executable and add them to a .zip file archive. This is the deployment package.

   ```
   chmod 755 function.sh bootstrap
   zip function.zip function.sh bootstrap
   ```

1. Create a function named `bash-runtime`. For `--role`, enter the ARN of your Lambda [execution role](lambda-intro-execution-role.md).

   ```
   aws lambda create-function --function-name bash-runtime \
   --zip-file fileb://function.zip --handler function.handler --runtime provided.al2023 \
   --role arn:aws:iam::123456789012:role/lambda-role
   ```

1. Invoke the function.

   ```
   aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out
   ```

   The **cli-binary-format** option is required if you're using AWS CLI version 2. To make this the default setting, run `aws configure set cli-binary-format raw-in-base64-out`. For more information, see [AWS CLI supported global command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) in the *AWS Command Line Interface User Guide for Version 2*.

   You should see a response like this:

   ```
   {
       "StatusCode": 200,
       "ExecutedVersion": "$LATEST"
   }
   ```

1. Verify the response.

   ```
   cat response.txt
   ```

   You should see a response like this:

   ```
   Echoing request: '{"text":"Hello"}'
   ```

## Create a layer
<a name="runtimes-walkthrough-layer"></a>

To separate the runtime code from the function code, create a layer that only contains the runtime. Layers let you develop your function's dependencies independently, and can reduce storage usage when you use the same layer with multiple functions. For more information, see [Managing Lambda dependencies with layers](chapter-layers.md).

1. Create a .zip file that contains the `bootstrap` file.

   ```
   zip runtime.zip bootstrap
   ```

1. Create a layer with the [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html?highlight=nodejs16%20x) command.

   ```
   aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip
   ```

   This creates the first version of the layer.

## Update the function
<a name="runtimes-walkthrough-update"></a>

To use the runtime layer in the function, configure the function to use the layer, and remove the runtime code from the function.

1. Update the function configuration to pull in the layer.

   ```
   aws lambda update-function-configuration --function-name bash-runtime \
   --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:1
   ```

   This adds the runtime to the function in the `/opt` directory. To ensure that Lambda uses the runtime in the layer, you must remove the `boostrap` from the function's deployment package, as shown in the next two steps.

1. Create a .zip file that contains the function code.

   ```
   zip function-only.zip function.sh
   ```

1. Update the function code to only include the handler script.

   ```
   aws lambda update-function-code --function-name bash-runtime --zip-file fileb://function-only.zip
   ```

1. Invoke the function to confirm that it works with the runtime layer.

   ```
   aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out
   ```

   The **cli-binary-format** option is required if you're using AWS CLI version 2. To make this the default setting, run `aws configure set cli-binary-format raw-in-base64-out`. For more information, see [AWS CLI supported global command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) in the *AWS Command Line Interface User Guide for Version 2*.

   You should see a response like this:

   ```
   {
       "StatusCode": 200,
       "ExecutedVersion": "$LATEST"
   }
   ```

1. Verify the response.

   ```
   cat response.txt
   ```

   You should see a response like this:

   ```
   Echoing request: '{"text":"Hello"}'
   ```

## Update the runtime
<a name="runtimes-walkthrough-runtime"></a>

1. To log information about the execution environment, update the runtime script to output environment variables.  
**Example bootstrap**  

   ```
   #!/bin/sh
   
   set -euo pipefail
   
   # Configure runtime to output environment variables
   echo "##  Environment variables:"
   env
   
   # Load function handler
   source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
   
   # Processing
   while true
   do
     HEADERS="$(mktemp)"
     # Get an event. The HTTP request will block until one is received
     EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
   
     # Extract request ID by scraping response headers received above
     REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
   
     # Run the handler function from the script
     RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
   
     # Send the response
     curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
   done
   ```

1. Create a .zip file that contains the new version of the `bootstrap` file.

   ```
   zip runtime.zip bootstrap
   ```

1. Create a new version of the `bash-runtime` layer.

   ```
   aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip
   ```

1. Configure the function to use the new version of the layer.

   ```
   aws lambda update-function-configuration --function-name bash-runtime \
   --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2
   ```

## Share the layer
<a name="runtimes-walkthrough-share"></a>

To share a layer with another AWS account, add a cross-account permissions statement to the layer's [resource-based policy](access-control-resource-based.md). Run the [add-layer-version-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-layer-version-permission.html) command and specify the account ID as the `principal`. In each statement, you can grant permission to a single account, all accounts, or an organization in [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html).

The following example grants account 111122223333 access to version 2 of the `bash-runtime` layer.

```
aws lambda add-layer-version-permission \
  --layer-name bash-runtime \
  --version-number 2 \  
  --statement-id xaccount \
  --action lambda:GetLayerVersion \
  --principal 111122223333 \
  --output text
```

You should see output similar to the following:

```
{"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2"}
```

Permissions apply only to a single layer version. Repeat the process each time that you create a new layer version.

## Clean up
<a name="runtimes-walkthrough-cleanup"></a>

Delete each version of the layer.

```
aws lambda delete-layer-version --layer-name bash-runtime --version-number 1
aws lambda delete-layer-version --layer-name bash-runtime --version-number 2
```

Because the function holds a reference to version 2 of the layer, it still exists in Lambda. The function continues to work, but functions can no longer be configured to use the deleted version. If you modify the list of layers on the function, you must specify a new version or omit the deleted layer.

Delete the function with the [delete-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/delete-function.html) command.

```
aws lambda delete-function --function-name bash-runtime
```

# Open source repositories
<a name="runtimes-open-source"></a>

AWS Lambda provides a variety of open source tools, libraries, and components to help you build, customize, and optimize your serverless applications. These resources include runtime interface clients, event libraries, container base images, development tools, and sample projects that are maintained by AWS and available on GitHub. By leveraging these open source repositories, you can extend Lambda's capabilities, create custom runtimes, process events from various AWS services, and gain deeper insights into your function's performance. This page provides an overview of the key open source projects that support Lambda development.

## Runtime Interface Clients
<a name="open-source-ric"></a>

Lambda Runtime Interface Clients (RICs) are open source libraries that implement the [Runtime API](runtimes-api.md) and manage the interaction between your function code and the Lambda service. These clients handle receiving invocation events, passing context information, and reporting errors.

The runtime interface clients used by Lambda's managed runtimes and container base images are published as open source. When you build custom runtimes or extend existing ones, you can use these open source libraries to simplify your implementation. The following open source GitHub repositories contain the source code for Lambda's RICs:
+ [Node.js Runtime Interface Client](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client)
+ [Python Runtime Interface Client](https://github.com/aws/aws-lambda-python-runtime-interface-client)
+ [Java Runtime Interface Client](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client)
+ [Ruby Runtime Interface Client](https://github.com/aws/aws-lambda-ruby-runtime-interface-client)
+ [.NET Runtime Interface Client](https://github.com/aws/aws-lambda-dotnet)
+ [Rust Runtime Interface Client](https://github.com/aws/aws-lambda-rust-runtime)
+ [Go Runtime Interface Client](https://github.com/aws/aws-lambda-go)
+ [Swift Runtime Interface Client](https://github.com/awslabs/swift-aws-lambda-runtime) (experimental)
+ [C\$1\$1 Runtime Interface Client](https://github.com/awslabs/aws-lambda-cpp) (experimental)
+ [Lambda Base Images](https://github.com/aws/aws-lambda-base-images)

For more information about using these clients to build custom runtimes, see [Building a custom runtime for AWS Lambda](runtimes-custom.md).

## Event libraries
<a name="open-source-event-libraries"></a>

Lambda event libraries provide type definitions and helper utilities for processing events from various AWS services. These libraries help you parse and handle event data in a type-safe manner, making it easier to work with events from services like Amazon S3, Amazon DynamoDB, and Amazon API Gateway.

For compiled languages, AWS provides the following event libraries:
+ [Java Event Library](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events)
+ [.NET Event Libraries](https://github.com/aws/aws-lambda-dotnet/tree/master/Libraries/src)
+ [Go Event Library](https://github.com/aws/aws-lambda-go/tree/main/events)
+ [Rust Event Library](https://github.com/awslabs/aws-lambda-rust-runtime)

For interpreted languages like Node.js, Python, and Ruby, events can be parsed directly as JSON objects without requiring a separate library. However, developers using Node.js and Python can leverage powertools for AWS Lambda, which provides built-in schemas for AWS events that offer type hinting, data validation, and functionality similar to what compiled language libraries provide.
+ [Powertools for TypeScript](https://docs.powertools.aws.dev/lambda/typescript/latest/features/parser/#built-in-schemas)
+ [Powertools for Python](https://docs.powertools.aws.dev/lambda/python/latest/utilities/parser/#built-in-models)

## Container base images
<a name="open-source-container-base-images"></a>

AWS provides open source container base images that you can use as a starting point for building container images for your Lambda functions. These base images include the runtime interface client and other components needed to run your functions in the Lambda execution environment.

For more information about the available base images and how to use them, see the [AWS Lambda Base Images](https://github.com/aws/aws-lambda-base-images) repository and [Create a Lambda function using a container image](images-create.md).

## Development tools
<a name="open-source-development-tools"></a>

AWS provides additional open source development tools to help you build and optimize your Lambda functions:

### Powertools for AWS Lambda
<a name="open-source-powertools"></a>

Powertools for AWS Lambda simplifies serverless development with essential utilities to prevent duplicate processing, and batch processing for multi-record handling and Kafka consumer library. These features help you minimize code complexity and operational overhead.

You can also leverage built-in event schema validation, structured logging and tracing, and parameter store integration which are designed to accelerate the creation of production-ready Lambda functions while following AWS well-architected best practices.

GitHub repositories:
+ [Python](https://github.com/aws-powertools/powertools-lambda-python)
+ [TypeScript](https://github.com/aws-powertools/powertools-lambda-typescript)
+ [Java](https://github.com/aws-powertools/powertools-lambda-java)
+ [.NET](https://github.com/aws-powertools/powertools-lambda-dotnet)

### Java development tools
<a name="open-source-java-tools"></a>
+ [Java Profiler (experimental)](https://github.com/aws/aws-lambda-java-libs/tree/main/experimental/aws-lambda-java-profiler) - A tool for profiling Java Lambda functions.
+ [ Java Libraries](https://github.com/aws/aws-lambda-java-libs) - A repository that contains a comprehensive collection of Java libraries and tools for Lambda development, including key projects such as JUnit testing utilities and profiling tools.
+ [Serverless Java Container](https://github.com/aws/serverless-java-container) - A library that enables you to run existing Java applications on Lambda with minimal changes.

### .NET development tools
<a name="open-source-dotnet-tools"></a>

The [AWS Lambda .NET](https://github.com/aws/aws-lambda-dotnet) repository provides .NET libraries and tools for Lambda development, including key projects such as for AWS Lambda tools for the .NET CLI and .NET Core server for hosting .NET Core applications.

## Sample projects
<a name="open-source-sample-projects"></a>

Explore a comprehensive collection of sample Lambda projects and applications at [Serverless Land repositories](https://serverlessland.com/repos). These samples demonstrate various Lambda use cases, integration patterns, and best practices to help you get started with your serverless applications.