
AWS Lambda Managed Instances でコールドスタートが発生しないことを確認してみた
こんにちは、製造ビジネステクノロジー部の若槻です。
AWS re:Invent 2025 で AWS Lambda 関数の新タイプである Lambda Managed Instances (LMI) が発表されました。
LMI では Lambda 関数が EC2 インスタンス上で稼働するため、定常的なリクエストをコスト効率よく処理することが可能となります。
加えて、「実行環境」がインスタンス上で常に起動していることになるため、コールドスタートが抑制されるというメリットもあります。
今回は、Lambda Managed Instances の Lambda 関数でコールドスタートが発生しないことを、デフォルト Lambda 関数と比較しつつ、実際に確認してみました。
確認してみた
Lambda ハンドラーコード
関数のハンドラーコードです。
import { Logger } from "@aws-lambda-powertools/logger";
import { Context } from "aws-lambda";
/**
* ロガーの初期化
*/
const logger = new Logger();
/**
* ハンドラー
*/
export const handler = async (context: Context): Promise<void> => {
logger.addContext(context);
logger.info("Hello, LMI");
};
ハンドラー外での AWS SDK クライアントの初期化という、コールドスタート発生時に Init フェーズに時間を要する典型的なコードパターンを使用しています。
CDK コード
リソースの作成には AWS CDK を使用しました。
VPC は予め作成したものを使用します。
VPC 定義コード
import * as ec2 from "aws-cdk-lib/aws-ec2";
import { Construct } from "constructs";
/**
* VPC 実装
*
* MEMO: VPC から各種 AWS サービスへのネットワーク経路確保のために NAT Gateway を配置する
*/
export class VpcConstruct extends Construct {
public readonly vpc: ec2.Vpc;
constructor(scope: Construct, id: string) {
super(scope, id);
this.vpc = new ec2.Vpc(this, "Default", {
subnetConfiguration: [
/**
* NAT Gateway を配置するためのパブリックサブネット
*/
{
name: "Public",
subnetType: ec2.SubnetType.PUBLIC,
},
/**
* Lambda 関数を配置するためのプライベートサブネット
*/
{
name: "PrivateWithEgress",
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
],
});
}
}
比較のために、デフォルト設定の Lambda 関数も作成します。
デフォルト Lambda 関数定義コード
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as lambda_nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";
/**
* デフォルト Lambda 関数実装
*
* MEMO: LMI との比較のために作成
*/
export class DefaultFunctionConstruct extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
new lambda_nodejs.NodejsFunction(this, "Default", {
entry: "src/handler.ts",
runtime: lambda.Runtime.NODEJS_24_X, // Lambda Managed Instances では Node.js 18.x 以上が必須
tracing: lambda.Tracing.ACTIVE, // コールドスタート発生状況の観測のために、AWS X-Ray を有効化
});
}
}
LMI 作成の定義は以下となります。
import * as cdk from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as lambda_nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";
import { DefaultFunctionConstruct } from "./constructs/default-function";
import { VpcConstruct } from "./constructs/vpc";
export class SampleStack extends cdk.Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
/**
* VPC 作成
*/
const vpcConstruct = new VpcConstruct(this, "Vpc");
const vpc = vpcConstruct.vpc;
/**
* セキュリティグループ作成
*
* MEMO: Capacity Provider 用に作成
*/
const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
vpc,
});
/**
* Capacity Provider 作成
*
* MEMO: LMI のコア要素となるリソース
*/
const capacityProvider = new lambda.CapacityProvider(
this,
"CapacityProvider",
{
subnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
}).subnets,
securityGroups: [securityGroup],
},
);
/**
* LMI 用 Lambda 関数作成
*/
const lmiFunction = new lambda_nodejs.NodejsFunction(this, "LmiFunction", {
entry: "src/handler.ts",
runtime: lambda.Runtime.NODEJS_24_X, // LMI では Node.js 22.x 以上が必須
tracing: lambda.Tracing.ACTIVE, // コールドスタート発生状況の観測のために、AWS X-Ray を有効化
});
/**
* Capacity Provider に Lambda 関数を追加
*/
capacityProvider.addFunction(lmiFunction);
/**
* 比較のためのデフォルト設定の Lambda 関数作成
*/
new DefaultFunctionConstruct(this, "DefaultFunction");
}
}
確認結果
それぞれの Lambda 関数を3回連続で呼び出した際の実行時間は下記の通りとなりました。デフォルト Lambda では 1 回目の呼び出しに1秒弱かかっているのに対し、LMI はいずれの実行も 0.02 秒で応答しています。2 回目以降の呼び出しでは両者とも高速に応答していますが、いずれの実行も LMI の方がわずかに高速です。
| デフォルト | LMI | |
|---|---|---|
| 1回目 | 0.807s | 0.017s |
| 2回目 | 0.058s | 0.023s |
| 3回目 | 0.042s | 0.011s |
X-Ray のトレースを確認したところ、デフォルト Lambda では 1 回目の実行で Init フェーズが記録されており、やはりコールドスタートが発生していることがわかります。

一方で LMI では 1 回目の実行でも Init フェーズ発生が記録されておらず、コールドスタートは発生していません。

結果として、LMI ではコールドスタートが発生しないことが確認できました!
トラブルシュート
CDK ではランタイムバージョンの明示的な指定が必要
LMI でサポートされている Lambda のランタイムバージョンは、従来 Lambda に比べてサポート範囲が最新のバージョンのみとなっています。Node.js の場合は 22 以上となります。
また NodejsFunction コンストラクトでランタイムバージョンを明示的に指定していない場合は、CDK デプロイ時に次のエラーが発生します。
8:55:42 PM | CREATE_FAILED | AWS::Lambda::Function | LambdaFunctionBF21E41F
Resource handler returned message: "Runtime Enum nodejs16.x does not support specified feature: Lambda Managed Instances (Service: Lambda, Status Code: 400, Request ID: 775b935f-0cdb-45
97-8ed1-755181991c5a) (SDK Attempt Count: 1)" (RequestToken: 0b0e7e16-980b-8f79-1a44-63310f922e12, HandlerErrorCode: InvalidRequest)
VPC から各種 AWS サービスへのネットワーク経路確保が必要
LMI の関数から各種 AWS サービスにアクセスさせるためには、NAT Gateway や VPC エンドポイントで VPC からのネットワーク経路を確保する必要があります。
ネットワーク経路が確保されていない場合は、下記のように CloudWatch Logs のイベントログが作成されないなどが起きえるので注意しましょう。

LMI でのログ出力上では全てコールドスタート扱いになる?(解決)
Lambda ハンドラーでは Powertools for AWS Lambda (TypeScript) を使用してログ出力を行っていますが、LMI でのログ出力上では全てコールドスタート扱いになってしまうようです。(2025/12/21 追記 Powertools for AWS Lambda を最新版にアップデートしたら解消しました。)
デフォルト Lambda を実行した場合は、1 回目の実行のみ cold_start":true が出力され、2 回目以降は cold_start":false が出力されます。

(2025/12/21 追記)一方で、同じコードで LMI を実行した場合は、1 回目から 3 回目まで全て cold_start":false が出力されました。

追記前の記述
一方で、同じコードで LMI を実行した場合は、1 回目から 3 回目まで全て cold_start":true が出力されてしまいます。

現状としては混乱を生む挙動となっているので、LMI での Powertools の対応が進むことを期待したいですね。
LMI でコールドスタートがなぜ発生しないのか?
ここで、LMI でなぜコールドスタートが発生しないのかを、Lambda の実行環境 (Execution Environment) のライフサイクルの観点からドキュメントをもとに確認してみます。
実行環境とは、AWS Lambda においてランタイムや関数が実行される場所を指します。

Lambda 実行環境のライフサイクルの概要 - AWS Lambda より
この実行環境のライフサイクルは、従来の Lambda と LMI では大きく異なっています。
従来 Lambda の場合
従来の Lambda の場合は、実行環境のライフサイクルは下記の3つのフェーズで構成されます。
- Init(初期化)
- Invoke(呼び出し)
- Shutdown(シャットダウン)

Lambda 実行環境のライフサイクルの概要 - AWS Lambda より
また従来の Lambda では、Invoke 完了後に直ちに Shutdown に移行せず、別の Invoke を待機してしばらく実行環境が維持されます。
維持された実行環境で Init を経ずに行われる Invoke をウォームスタートと呼び、新しい実行環境で Init から行われる Invoke をコールドスタートと呼びます。コールドスタートの場合は Init フェーズが含まれるため、呼び出し側から見たレイテンシーが大きくなります。
下記は関数が 10 個のリクエストを受け取った様子の図ですが、このうち1,2,3,4,5,9がコールドスタート、6,7,8,10がウォームスタートに該当します。

Lambda 関数のスケーリングについて - AWS Lambda より
従来 Lambda は1つの実行環境上で一度に1つの Invoke しか実行できない(上図のように直列となる)ため、リクエスト増加時にコールドスタートが発生しやすいという課題がありました。
LMI の場合
一方 LMI の場合は、実行環境のライフサイクルが異なっており、
- 実行環境があらかじめ起動しているため、Init フェーズが呼び出し側から隠蔽されている
- 1つの実行環境上で一度に複数の Invoke を並列して実行可能
となっています。これが LMI でコールドスタート発生が抑えられる理由となります。
おわりに
今回は Lambda Managed Instances の Lambda 関数でコールドスタートが発生しないことを、デフォルト Lambda 関数と比較しつつ確認してみました。
サービス発表時の AWS ブログで「初回リクエストのレイテンシに影響するコールドスタートを排除します」とあり、本当かなーと半信半疑でしたが、実際に確認してみると如実にコールドスタートが起きないことが分かりました。
ただし、同ブログには「キャパシティプロバイダーが最大プロビジョニング容量に達し、追加キャパシティがまだ立ち上げ中の場合、リクエストを一時的に 429 ステータスコードで制限します。」ともあり、トラフィック急増時にスケーリングが間に合わずにリクエストが制限される可能性はあるので、トラフィックパターンに応じてスケーリングポリシーやインスタンス選定の検討は必要そうですね。
参考
- CDK コード参考
以上







