Lambda タイムアウト設定を変更する方法:上限・注意点・実運用パターン

Lambda 関数が 3 秒で強制終了されるのに、処理には 10 秒必要——このギャップに気づくのは大抵、本番で初めてタイムアウトエラーを踏んだときだ。デフォルトの 3 秒という設定は「軽量な同期処理」を想定したものであり、外部 API 呼び出しやデータ変換処理を含む関数には最初から合っていない。この記事では Lambda タイムアウトの変更手順、上限値、そして設定ミスが引き起こす実運用上の問題を具体的に解説する。

TL;DR:Lambda タイムアウト設定の要点

項目内容
デフォルト値3 秒
最大値900 秒(15 分)
変更スコープ関数レベル(バージョン・エイリアス単位ではない)
変更方法AWS コンソール / AWS CLI / IaC(CloudFormation・Terraform)
課金への影響タイムアウト値ではなく実際の実行時間で課金される
関連する上流サービスの制限API Gateway の統合タイムアウトは最大 29 秒(変更不可)

Lambda タイムアウトの仕組みを理解する

Lambda のタイムアウトは「関数が起動してから強制終了されるまでの最大壁時計時間」だ。CPU 時間でも I/O 待機時間でもなく、呼び出しから終了までの経過時間で計測される。設定値に達した瞬間、Lambda ランタイムはハンドラーを問答無用で終了させ、呼び出し元には Task timed out after X.XX seconds というエラーを返す。

重要なのは、タイムアウトは関数設定に紐づくという点だ。同一コードを使う複数の関数があれば、それぞれ独立して設定できる。また、Lambda レイヤーや VPC 設定はタイムアウト値に影響しないが、コールドスタートの初期化時間はタイムアウトのカウントに含まれる。

graph LR A["呼び出し開始
タイマースタート"] --> B["関数処理中"] B --> C{"タイムアウト
到達?"} C -- "No: 正常終了" --> D["レスポンス返却
タイマー停止"] C -- "Yes: 強制終了" --> E["Task timed out
エラー返却"]
  1. 呼び出し開始:Lambda サービスがハンドラーを起動し、タイムアウトカウンターが開始する。
  2. 処理継続:設定したタイムアウト値の範囲内であれば関数は正常に動作し続ける。
  3. 正常終了:ハンドラーが値を返すか例外を送出すれば、カウンターはリセットされる。
  4. タイムアウト強制終了:制限時間を超えると Lambda ランタイムが関数を強制終了し、エラーを返す。

Lambda タイムアウトを変更する 3 つの方法

方法 1:AWS マネジメントコンソール

Lambda コンソールで対象の関数を開き、「設定」→「一般設定」→「編集」 と進む。「タイムアウト」フィールドに分・秒単位で値を入力して保存するだけだ。即時反映されるため、動作確認の最初のステップとして使いやすい。

方法 2:AWS CLI

スクリプトや CI/CD パイプラインから変更する場合は update-function-configuration を使う。--timeout には秒単位の整数を指定する。

aws lambda update-function-configuration \
  --function-name my-function \
  --timeout 30 \
  --region us-east-1

変更後の設定を確認する:

aws lambda get-function-configuration \
  --function-name my-function \
  --region us-east-1 \
  --query 'Timeout'

方法 3:CloudFormation / SAM

インフラをコードで管理している場合は、テンプレートの Timeout プロパティを直接変更する。

Resources:
  MyFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: my-function
      Runtime: python3.12
      Handler: index.handler
      Timeout: 30
      Role: arn:aws:iam::123456789012:role/MyLambdaRole
      Code:
        S3Bucket: my-deployment-bucket
        S3Key: function.zip

Lambda タイムアウト設定に必要な IAM 権限

タイムアウトを変更するには lambda:UpdateFunctionConfiguration 権限が必要だ。読み取り専用の確認には lambda:GetFunctionConfiguration を使う。最小権限ポリシーの例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:UpdateFunctionConfiguration",
        "lambda:GetFunctionConfiguration"
      ],
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function"
    }
  ]
}

タイムアウト設定で見落としがちな上流サービスの制限

Lambda のタイムアウトを 30 秒に伸ばしたのに、相変わらず 29 秒でエラーになる——これは Lambda の問題ではなく API Gateway の問題だ。

API Gateway(REST API・HTTP API)の統合タイムアウトは最大 29 秒に固定されており、Lambda 側のタイムアウトをどれだけ長くしても API Gateway が先に接続を切る。この制限は AWS のドキュメントに明記されており、変更できない。

API Gateway 経由で 29 秒を超える処理を実行しようとするのは、蛇口の流量をいくら増やしても配管の径が変わらないのと同じだ。Lambda のタイムアウトを伸ばす前に、呼び出し元の制限を確認する必要がある。

29 秒を超える処理が必要な場合、一般的なアーキテクチャパターンは「非同期化」だ。API Gateway から Lambda を非同期で呼び出し、処理状態を DynamoDB などに記録して、クライアントがポーリングまたは WebSocket で結果を受け取る構成に切り替える。

graph TD subgraph SYNC ["同期パターン(最大 29 秒)"] A1["クライアント"] --> B1["API Gateway"] B1 --> C1["Lambda
タイムアウト ≤ 29s"] C1 --> B1 B1 --> A1 end subgraph ASYNC ["非同期パターン(最大 900 秒)"] A2["クライアント"] --> B2["API Gateway"] B2 --> C2["Lambda 受付
即時 202 返却"] C2 --> D2["SQS"] D2 --> E2["Lambda 処理
タイムアウト ≤ 900s"] E2 --> F2["DynamoDB
結果保存"] A2 -- "ポーリング" --> F2 end
  1. 同期呼び出し(29 秒以内):API Gateway → Lambda の直接統合。Lambda のタイムアウトは 29 秒以下に設定する必要がある。
  2. 非同期呼び出し(最大 15 分):API Gateway → Lambda(受付)→ SQS/SNS → Lambda(処理)の構成。処理 Lambda のタイムアウトは最大 900 秒まで設定できる。

実運用で踏んだパターン:タイムアウト変更後もエラーが続く

症状:Lambda のタイムアウトを 60 秒に変更したが、CloudWatch Logs には依然として Task timed out after 3.00 seconds が記録され続けた。

最初の誤診:設定の反映に時間がかかっていると思い、数分待ってから再テストした。結果は同じだった。

実際の原因:関数に発行済みバージョン($LATEST 以外)が存在し、呼び出し元のエイリアスがその古いバージョンを指していた。Lambda のタイムアウト設定はバージョン発行時にスナップショットされるため、$LATEST の設定を変更しても発行済みバージョンには反映されない。

修正手順:

# 現在のエイリアスが指しているバージョンを確認する
aws lambda get-alias \
  --function-name my-function \
  --name production \
  --region us-east-1

# $LATEST のタイムアウトを変更後、新しいバージョンを発行する
aws lambda publish-version \
  --function-name my-function \
  --region us-east-1

# エイリアスを新しいバージョンに更新する(バージョン番号は上記の出力で確認)
aws lambda update-alias \
  --function-name my-function \
  --name production \
  --function-version 5 \
  --region us-east-1

発行済みバージョンのタイムアウト値は変更できない。設定を変えるには、$LATEST を修正してから新バージョンを発行し、エイリアスを切り替えるのが正しい手順だ。

タイムアウト値の決め方:実測ベースのアプローチ

「とりあえず最大の 900 秒にしておけばいい」という判断は避けたほうがいい。タイムアウトを必要以上に長く設定すると、バグによる無限ループや外部 API のハング時に Lambda が長時間実行され続け、コストと同時実行数の枠を無駄に消費する。

実測値に基づいて設定する手順:

# 関数の実行時間を CloudWatch Logs Insights で確認する
aws logs start-query \
  --log-group-name /aws/lambda/my-function \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'filter @type = "REPORT" | stats max(@duration), avg(@duration), pct(@duration, 95) by bin(5m)' \
  --region us-east-1

95 パーセンタイルの実行時間を基準に、余裕を持たせた値(例:P95 の 2〜3 倍)をタイムアウトとして設定するのが現実的なアプローチだ。P99 や最大値ではなく P95 を基準にするのは、外れ値に引きずられた過剰なタイムアウトを避けるためだ。

Lambda タイムアウト設定のまとめと次のステップ

Lambda タイムアウトの変更自体は単純な操作だが、上流サービスの制限(API Gateway の 29 秒)、発行済みバージョンへの非反映、そして過剰なタイムアウト設定によるコスト増という 3 つの落とし穴を理解しておくことが重要だ。

次のステップとして以下を確認することを推奨する:

  • CloudWatch Logs Insights で現在の P95 実行時間を計測し、適切なタイムアウト値を決定する
  • 呼び出し元が API Gateway の場合、29 秒制限に対して処理を非同期化できるか検討する
  • Lambda の同時実行数制限(デフォルトのアカウントレベル上限)も合わせて確認する
  • 公式ドキュメント:AWS Lambda 関数の設定

用語集

用語説明
タイムアウト(Timeout)Lambda 関数の呼び出しから強制終了までの最大経過時間。1〜900 秒の範囲で設定可能。
$LATESTLambda 関数の最新の未発行バージョン。設定変更は常にここに反映される。
発行済みバージョン(Published Version)$LATEST のスナップショット。発行後は設定(タイムアウトを含む)を変更できない。
エイリアス(Alias)特定のバージョンへの名前付き参照。本番・ステージングなどの環境切り替えに使う。
統合タイムアウト(Integration Timeout)API Gateway がバックエンドサービスからのレスポンスを待つ最大時間。REST API・HTTP API ともに最大 29 秒。

Related Posts

コメント

このブログの人気の投稿

EC2 SSH接続タイムアウトの原因と修正方法 — セキュリティグループのインバウンドルール完全ガイド

S3パブリックアクセス拒否の原因と解決策:バケットレベルの「Block Public Access」が優先される仕組み

EC2インスタンスIDをメタデータから取得する方法 — IMDSv2が安全な理由