Lambda の同一インスタンスはどれくらいの時間が空くと落ちるのか測ったら 5〜6 分くらいだった

Lambda のスケーリングはコンピューティングリソースベースではなく実行数ベースによるものです。つまり「ある 1 つのインスタンスが既に実行されているときにもうひとつ別のリクエストが来た場合は単純に 2 つめのインスタンスが起動する」という具合。

これが「同時実行数」という概念で、例えば関数ごとにこの同時実行数をあからじめ予約しておくことでアカウント全体の同時実行数の上限値(デフォルトで 1,000)を食いつぶさないようにする、などが可能になります。

そして、ある 1 つのインスタンスは「ある程度断続的にリクエストが来続ける限りは同じものが再利用される」という性質もよく知られています。これはコールドスタートであるかホットスタートであるかという話題とほぼ同義です。

この「一体どれくらいの起動頻度なら 1 つのインスタンスが破棄されずにホットスタートになり続けるのか」というのはなんとなくの体感時間でしか知らず、ずっと気になっていました。

ググってみても関係のありそうな情報が全く出てこないのを見るに、おそらく固定で決まっているわけではなく AWS 側の様々な事情により上下していそうな雰囲気を感じてはいるものの、ちゃんと測ってみようということで今回やってみました。

測ってみましたとはいうものの実験はだいぶおざなりです。

結果は 5〜6 分くらいで、自分のこれまでの経験による体感値は 10~15 分程度だったのでだいぶ乖離があります。変動する要因はいっぱいありそうです。

実験

どうやって Lambda が前と同じインスタンスを使用しているかどうかを調べるかですが、だいたい下記のようなものが根拠になると思います:

  • Lambda の cold_start が true/false のどちらだったか CloudWatch Logs から確認する(AWS Lambda Powertools for Pythonlogger.inject_lambda_context を使うと確認できる)
  • CloudWatch Logs のログストリームが分離しているかどうか確認する

というわけで、実験の手順は以下のようになりました。

  1. 誰にも使われていないことが確実である適当な Lambda を適当に実行
  2. CLoudWatch Logs に新しいログストリームが生成された& cold_start: true を確認
  3. まずは 15 分後に再実行してみる
  4. 新規インスタンスだったので次は 10 分後に再実行
  5. 新規インスタンスだったので次は 7 分後に再実行
  6. 新規インスタンスだったので次は 5 分後に再実行
  7. 同一インスタンスが再利用されたので 6 分後に再実行
  8. 新規インスタンスだった

ということで、この実験からのみの結果だと 5〜6 分くらいとなります。根拠の弱さはみなさんも感じられているとおりで、おそらく僕がこれまでになんとなく思っていた体感値(商用サービスの開発中ログや実際の本番ログによるもの)との環境や実験条件の違いがそのまま結果に影響していそうです。

例えば、

  • その関数全体の呼び出される数、頻度、使用コンピューティングリソース量の違い
  • 同時実行数が 1 なのか複数あるのか

などでしょうか。

いずれにしても具体的な値が公開されていない以上変動するものでありそうなのは間違いなくて、「なんとなく 5 分〜 15 分程度」くらいに思っておいていいのではと思います。この数字をアプリケーション設計の中で頼りにすることはないはずなので。