SJ blog
backend
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

Lambda同時実行 — 予約済み/プロビジョニング済み・スロットリング・アカウント上限

Lambda同時実行の仕組み、アカウントレベルの上限(1000)、予約済み同時実行(Reserved)とプロビジョニング済み同時実行(Provisioned)の違い、コールドスタート対策を解説。

一言結論

Lambdaの同時実行はアカウント全体で上限を共有するため、重要な関数は予約済み同時実行で保護し、コールドスタートが許容できない用途にはプロビジョニング済み同時実行を使うのが実運用の基本戦略だ。

Lambda同時実行の仕組み

Lambda関数は各リクエストを個別の「実行環境(Execution Environment)」で処理する。複数リクエストが同時に来ると、複数の実行環境が並列で起動する。

同時実行数 = 同時に処理中のリクエスト数

例: 100リクエストが同時に来る場合
  → 最大100の実行環境が並列起動
  → 各環境が1リクエストを処理

アカウントレベルの同時実行上限

デフォルトでリージョンごとに1,000の同時実行が上限だ(引き上げ可能)。

1アカウントのデフォルト: 1,000同時実行

この上限をすべての関数で共有する
→ 関数Aが900を使っている場合、関数B/Cは合計100しか使えない

予約済み同時実行(Reserved Concurrency)

特定の関数に最大同時実行数を「予約」または「制限」する。

# 予約済み同時実行を設定
aws lambda put-function-concurrency \
  --function-name my-function \
  --reserved-concurrent-executions 100
用途1: 上限を設定する(過剰スケールを防ぐ)
  例: バッチ処理関数が1,000全部を使い尽くさないように制限
  reserved: 50 → この関数は最大50まで、残り950は他の関数で使える

用途2: 最低保証を設定する(他の関数に圧迫されない)
  reserved: 100 → この関数は常に最低100は確保される
  
重要: 予約済み同時実行を0に設定するとスロットリングが発生(関数を無効化)

プロビジョニング済み同時実行(Provisioned Concurrency)

コールドスタートを排除するために、実行環境を事前にウォームアップして待機させる。

# プロビジョニング済み同時実行を設定
aws lambda put-provisioned-concurrency-config \
  --function-name my-function \
  --qualifier production \
  --provisioned-concurrent-executions 50
コールドスタートとは:
  新しい実行環境の初期化(関数コードのロード、依存関係の初期化)
  発生タイミング: 実行環境が存在しない場合(スケールアウト時、アイドル後)
  追加時間: Java等のランタイムでは数秒、Python/Nodeでは数百ミリ秒

プロビジョニング済みの動作:
  → 50の実行環境を常時ウォームアップ状態で待機
  → 最初の50リクエストはコールドスタートなしで処理
  → 51リクエスト目以降は通常の(コールドスタートあり)処理

コスト計算

プロビジョニング済み同時実行のコスト:
  設定した数 × 設定時間 × GB-秒料金(通常の2倍程度)
  例: 10プロビジョニング × 1時間 × 512MB = $0.015程度

使う状況:
  - API GatewayバックエンドでP99レイテンシーの要件がある
  - 定期的なトラフィックスパイク(予測可能なパターン)

Auto Scalingとの組み合わせ

# プロビジョニング済みの自動スケーリング
aws application-autoscaling register-scalable-target \
  --service-namespace lambda \
  --resource-id function:my-function:production \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --min-capacity 10 \
  --max-capacity 100

# ターゲット追跡スケーリング(70%使用率を目標)
aws application-autoscaling put-scaling-policy \
  --service-namespace lambda \
  --resource-id function:my-function:production \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --policy-name provisioned-scaling \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 0.7,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "LambdaProvisionedConcurrencyUtilization"
    }
  }'

スロットリングの対応

予約済み同時実行数または上限に達した場合、TooManyRequestsException (HTTP 429) が返る。

# 呼び出し側でのリトライ(指数バックオフ)
import boto3
from botocore.config import Config

lambda_client = boto3.client('lambda', config=Config(
    retries={
        'max_attempts': 5,
        'mode': 'adaptive'  # 指数バックオフ + ジッター
    }
))

# 非同期呼び出し(InvokeType=Event)の場合
# AWSが自動でリトライ(最大2回)し、失敗時はDLQに送る

バースト制限

新しいリクエストが急増した場合、Lambdaは一定速度でスケールアップする(すべてが瞬時に起動するわけではない)。

バースト制限(東京リージョン):
  初期バースト: 3,000同時実行(瞬時に追加可能)
  それ以降: 毎分500ずつ追加

例: 10,000リクエストが突然来た場合
  最初: 3,000を即座に処理
  1分後: 3,500
  2分後: 4,000
  → 10,000全てが処理されるまで約15分かかる

試験頻出ポイント

シナリオ回答
コールドスタートを排除したいプロビジョニング済み同時実行
バッチ処理がアカウント上限を使い尽くす問題バッチ処理にReserved Concurrencyで上限を設定
Lambda関数を一時的に無効化したいReserved Concurrencyを0に設定
アカウントデフォルトの同時実行上限1,000(リクエストで引き上げ可能)
スロットリング発生時のHTTPステータスコード429 (TooManyRequests)

まとめ

Lambdaの同時実行管理は「アカウント上限の共有管理(Reserved)」と「コールドスタート排除(Provisioned)」の2軸で考える。本番APIにはProvisionedでコールドスタートを防ぎ、バッチ処理にはReservedで上限を設けて他の関数への影響を制御する。