本記事の計測は 2026 年 10 月時点のものです。Lambda Web Functions は発表直後で、Jev はベータ提供のため、仕様や料金は変わる可能性があります。
1. はじめに
2026 年 10 月 12 日に、AWS Lambda に Web Functions という新しい種類の関数が追加されました1。HTTP サーバーをそのまま Lambda で動かす方式で、1 つの実行環境が複数のリクエストを同時に処理します。同じ発表で、これまでの Lambda 関数は Event Functions という名前に変わりました1。本記事でもこの呼び方を使います。料金について、発表には次の一文があります。
You pay for active CPU time and the memory your environment holds.
(訳: 課金されるのは、実際に使った CPU 時間と、実行環境が確保しているメモリです)
料金ページには、メモリは消費した量で、実行環境が動いている間ずっと課金されると書かれています2。外部の API の応答を待っている間は CPU を使わないので、待ち時間の長い処理ほど安くなると考えられます。
手元に、待ち時間がほとんどを占めるアプリがあります。AWS のサービス名を入れると、それが「Amazon 〜」か「AWS 〜」かを Jev に答えさせる小さなアプリです。Jev は TypeSafe AI が API で提供している AI モデルで、文章を生成せず、与えた選択肢から答えを確率つきで返します3。アプリは CloudFront の後ろに置いた Event Functions(Python)で動かしていて、処理時間の大半は Jev の応答待ちです。このアプリを Web Functions に載せ替えて、Event Functions と料金と速さを比べてみました。

図 1: 判定アプリの画面。サービス名を選ぶと、Jev が「Amazon 〜」か「AWS 〜」かを確率つきで返す(載せ替え後の Web Functions で Lambda を判定した例)
Web フレームワークの Hono で書いたアプリで Web Functions と Event Functions を比べた記事が先に出ています4。そちらは Event Functions を Web Functions と同じ 2,048 MB にそろえ、メトリクスから料金を試算しています。本記事では、Event Functions を普段使っている 256 MB のまま、CloudFront 越しに外部 API を呼ぶ実際のアプリで比べます。あわせて、リクエストが途絶えたあとに実行環境が残る時間と数を見て、料金の計算を Cost Explorer の使用量で確かめます。
比べたのは次の 4 つの構成です。どれも同じアプリで、CloudFront の後ろに置いています(設定は 2 章)。以降、構成は表の 1 列目の名前で書きます。本文で主に比べるのは ② と ④ で、① は元のアプリの参考、③ は ② のメモリを増やしたときの比較として載せます。
| 構成 | 役割 |
|---|---|
| ① Event Functions(Python・256 MB) | 元のアプリそのもの |
| ② Event Functions(Node.js・256 MB) | ④ と同じ Node.js のコードで、関数の種類だけを変えた比較 |
| ③ Event Functions(Node.js・1,769 MB) | ② と同じ関数のメモリを 1 vCPU 相当まで増やした比較 |
| ④ Web Functions | 載せ替え先 |
本記事では、35 分以上リクエストを送らずに置いたあとの最初のリクエストを「コールドスタートの 1 本目」と呼びます。③ だけは 35 分空けておらず、メモリの設定を変えて実行環境を作り直した直後の 1 本目です(5 章)。
1.1. 結論(先出し)
- 同時 10 本の判定を 30 秒間送り続けたとき、1 万判定あたりの料金は ④ Web Functions が約 0.0054 ドルで最も安く、② Event Functions(Node.js・256 MB)は約 0.0071 ドルだった。② のコールドスタートを速くするためにメモリを 1,769 MB にした ③ は約 0.034 ドルで、② の約 5 倍になった
- 起動済みの状態では、応答時間の中央値は ④ が 156 ms、② が 166 ms で 10 ms の差だった。コールドスタートの 1 本目は ② だけ約 1.8 秒かかり、実行環境を作り直した直後の ③ では 0.6〜0.9 秒だった
- ④ Web Functions の料金はリクエストの届き方で変わる。同時 20 本を 2 分間送り続けると、処理する実行環境は最初の 3 個から約 1 分ごとに 1 個ずつ減り、最後は 1 個の実行環境が 20 本を同時に処理した。一度にまとめて送ると多くの実行環境に分かれ、途絶えたあとも最後の実行環境が約 5〜7 分残って、消費メモリ × 稼働時間で課金された
1.2. 検証ゴール
| # | 確かめること | 確認できれば OK の条件 |
|---|---|---|
| 1 | Node.js に移植したアプリが、入口のファイルを変えるだけで Web Functions でも動くか | CloudFront の URL で画面が開き、判定結果が Event Functions と同じ形式で返る |
| 2 | 同じ負荷で料金がどれだけ違うか | 4 つの構成について、1 万判定あたりの料金を課金対象の量と単価から計算できる |
| 3 | 応答時間とコールドスタートに差が出るか | 4 つの構成について、応答時間の中央値・95 パーセンタイルとコールドスタートの 1 本目の秒数が並ぶ |
| 4 | Web Functions の実行環境の数と料金が、リクエストの届き方でどう変わるか | 送り続けたときと一度にまとめて送ったときで、処理した実行環境の数と、途絶えたあとに残る時間が分かる |
2. 検証環境
4 つの構成の設定は次のとおりです。アプリの中身はすべて同じで、Python 版はそれを Node.js に移植する前の元のコードです。
| 構成 | 関数の種類 | ランタイム | アーキテクチャ | メモリ | 入口 |
|---|---|---|---|---|---|
| ① Event Functions(Python・256 MB) | Event Functions | Python 3.12 | x86_64 | 256 MB | Function URL |
| ② Event Functions(Node.js・256 MB) | Event Functions | Node.js 24 | Arm64 | 256 MB | Function URL |
| ③ Event Functions(Node.js・1,769 MB) | Event Functions | Node.js 24 | Arm64 | 1,769 MB | Function URL |
| ④ Web Functions | Web Functions | Node.js 24(nodejs24.x) |
Arm64 | 選べない(上限 2 GB) | Web Functions のエンドポイント |
4 つの構成に共通する環境は次のとおりです。
| 項目 | 値 |
|---|---|
| リージョン | ap-northeast-1(東京) |
| 前段 | CloudFront(構成ごとに 1 つ、OAC あり、キャッシュ無効)。OAC は Origin Access Control の略で、CloudFront がオリジンへのリクエストに署名する仕組み |
| アプリ | Hono 4.10.4、@hono/node-server 1.19.5 |
| Jev |
jev-latest(応答時に返るモデル名は jev-1.13.0) |
| AWS CLI | 2.38.0(aws lambda-web コマンドを含む版) |
| 計測クライアント | 手元の Windows PC(Node.js 24.12.0、fetch で同時にリクエストを送る) |
③ Event Functions(Node.js・1,769 MB)は、5 章のコールドスタートの遅さの原因を確かめるために後から追加しました。Event Functions は 1,769 MB で 1 vCPU 相当の CPU が割り当てられます5。
検証に使った AWS アカウントは、Event Functions の同時実行数の上限が 10 でした(aws lambda get-account-settings の ConcurrentExecutions)。Web Functions の Arm の vCPU の上限も 200 で、どちらもデフォルト値(1,000 と 2,000)より低い値です67。公式には、新しいアカウントは同時実行数と Web Functions の vCPU などの上限が低く設定されていて、使用状況に応じて自動で引き上げられると書かれています6。同時 10 本の計測は、Event Functions の同時実行数の上限と同じ本数です。
3. 載せ替え

図 2: 比べた 4 つの構成。Web Functions と Event Functions をそれぞれ CloudFront の後ろに置き、同じ手順で計測した
3.1. Python から Hono への移植
元のアプリは Python の Lambda 関数 1 本で、GET / で画面の HTML を返し、POST /judge で受け取ったサービス名を Jev に渡して、正解と突き合わせた結果を返します。Web Functions は発表時点で Node.js だけに対応している1ので、Hono で書き直しました。
アプリ本体(app.mjs)は 1 つにして、入口だけを関数の種類ごとに分けています。
// Web Functions の入口(server.mjs)。待ち受け先は環境変数で渡される
import { serve } from "@hono/node-server";
import { app } from "./app.mjs";
const ep = process.env.AWS_LAMBDA_HTTP_ENDPOINT; // "host:port"
const [hostname, port] = ep ? [ep.split(":")[0], Number(ep.split(":")[1])] : ["0.0.0.0", 8080];
serve({ fetch: app.fetch, hostname, port });
// Event Functions の入口(event.mjs)。同じ app を Function URL のイベントで呼ぶ
import { handle } from "hono/aws-lambda";
import { app } from "./app.mjs";
export const handler = handle(app);
Web Functions では、アプリは環境変数 AWS_LAMBDA_HTTP_ENDPOINT に host:port の形式で渡される場所で待ち受けます8。ルーティングや Jev の呼び出しは app.mjs のまま共通です。
同時処理の様子を見るために、利用ログ(1 判定 1 行の JSON)に env_id と inflight を追加しました。env_id はプロセスの起動時に 1 回だけ作る ID で、同じ値なら同じ実行環境が処理しています。inflight は、そのリクエストを受けた時点で同じ実行環境が処理中だったリクエストの数(自分を含む)です。計測用に、sleep_ms で指定した時間だけ待ってから env_id と inflight を返す GET /whoami も追加しました(Jev は呼びません)。
3.2. Web Functions の作り方
Web Functions は aws lambda ではなく、別の aws lambda-web コマンドで作ります9。deploy を 1 回実行すると、関数・最初のリビジョン(あとから変更できない、コードと設定の組)・エンドポイントがまとめてできます。
# dist/ は app.mjs・server.mjs・node_modules などを入れたディレクトリ
aws lambda-web deploy --name jev-judge-web --code ./dist --runtime nodejs24.x \
--execution-role-arn arn:aws:iam::<account-id>:role/<lambda-exec-role> \
--env AWS_LAMBDA_NODEJS_ENTRYPOINT=server.mjs --env APP_FORM=web \
--timeout-seconds 60 --auth-type IamAuth --create
パッケージには node_modules も含めます。入口のファイルはデフォルトで index.js なので、server.mjs から起動するように環境変数 AWS_LAMBDA_NODEJS_ENTRYPOINT を指定しました9。タイムアウトは元のアプリと同じ 60 秒にしています(Web Functions のデフォルトは 30 秒6)。コードの zip は、deploy が作るバージョニング有効の S3 バケットに置かれます。
手元の AWS CLI 2.36.19 には lambda-web コマンドが無く、2.38.0 に更新して使いました。メモリとアーキテクチャは選べず、1 つの実行環境に Arm の vCPU 2 個とメモリ 2 GB が上限として割り当てられます6。
載せ替えで確かめた制約は、ほかに 2 つあります。サーバーは AWS_LAMBDA_HTTP_ENDPOINT の場所で、起動から 10 秒以内に待ち受けを始める必要があります10。1 つの実行環境が複数のリクエストを同時に処理するので、リクエストごとの値をグローバル変数に置かないようにします10。
3.3. CloudFront の後ろに置く
元のアプリと同じく、CloudFront の後ろに置いて、関数を直接は呼べないようにしました。エンドポイントの認証を IamAuth にし、CloudFront の OAC で署名させます11。Event Functions と Web Functions で変えた設定は次の表のとおりです。
| 設定 | Event Functions(Function URL) | Web Functions |
|---|---|---|
| オリジン側の認証 | Function URL の AWS_IAM
|
エンドポイントの IamAuth
|
| OAC の署名動作 | always |
always-amz-auth(選べるのはこれだけ) |
| オリジンへの許可 |
lambda:InvokeFunctionUrl と lambda:InvokeFunction を cloudfront.amazonaws.com に |
lambda:InvokeWebFunctionEndpoint を cloudfront.amazonaws.com に |
| オリジンリクエストポリシー | AllViewerExceptHostHeader |
AllViewerExceptHostHeader |
Web Functions への許可は、aws lambda-web put-resource-policy で関数に付けます。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "lambda:InvokeWebFunctionEndpoint",
"Resource": "arn:aws:lambda:ap-northeast-1:<account-id>:web-function/jev-judge-web/endpoint/dev",
"Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:cloudfront::<account-id>:distribution/<distribution-id>" } }
}]
}
ここまでで、4 つの構成とも CloudFront の URL で画面が開き、POST /judge に同じ形式の結果が返りました(検証ゴール 1)。
元のアプリでは、POST の本文の SHA-256 を x-amz-content-sha256 ヘッダーに入れないと、Function URL が 403 を返しました12。そのため画面の JavaScript でハッシュを計算して付けていました。Web Functions の OAC は本文を UNSIGNED-PAYLOAD として署名するため、このヘッダーは不要だと公式ドキュメントに書かれています11。OAC 越しの POST で、ヘッダーの有無を変えて確かめました。
x-amz-content-sha256 |
Event Functions(Function URL) | Web Functions |
|---|---|---|
| なし | 403(署名の不一致) | 200 |
| あり | 200 | 200 |
Web Functions に載せ替えるなら、画面側でハッシュを計算する処理は消せます。
4. 安くなるか
同時 10 本の判定を 30 秒間送り続けたとき、1 万判定あたりの料金は ④ Web Functions が最も安く、② Event Functions(Node.js・256 MB)の約 4 分の 3 でした。② のメモリを 1,769 MB に増やした ③ は、② の約 5 倍です。
以下、この「同時 10 本の判定を 30 秒間送り続ける」計測を「持続負荷」と呼びます。料金は、課金対象の量と東京リージョンの単価から計算しました。単価の取得元と計算式、Cost Explorer の使用量との照合は付録 A に載せます。Jev の料金は含めていません。
| 構成 | 判定数(200 が返った数) | 課金対象の量 | 30 秒間の合計 | 1 万判定あたり |
|---|---|---|---|---|
| ① Event Functions(Python・256 MB) | 1,632 | 請求対象の実行時間 263.0 秒 | 0.00142 ドル | 0.0087 ドル |
| ② Event Functions(Node.js・256 MB) | 1,738 | 請求対象の実行時間 265.2 秒 | 0.00123 ドル | 0.0071 ドル |
| ③ Event Functions(Node.js・1,769 MB) | 1,858 | 請求対象の実行時間 258.4 秒 | 0.00632 ドル | 0.0340 ドル |
| ④ Web Functions | 1,821 | vCPU の稼働時間 10.4 秒、実行環境 3 個 × 稼働時間 30.2 秒 × 消費メモリ 267 MB | 0.00098 ドル | 0.0054 ドル |
Web Functions は、リクエスト数と、vCPU の稼働時間と、消費したメモリ × 実行環境の稼働時間で課金されます2。Event Functions は、リクエスト数と、設定したメモリ × 請求対象の実行時間で課金されます2。
差が出たのは、Jev の応答を待っている時間の扱いです。今回のアプリは 1 判定約 150 ms のうちほとんどが Jev の応答待ちで、30 秒間の ④ の vCPU の稼働時間は 10.4 秒、② の請求対象の実行時間は 265.2 秒でした。② では待ち時間がそのまま課金されるのに対し、④ では待ち時間は vCPU の稼働時間に数えられず、メモリも 3 個の実行環境の分だけでした。④ のリクエスト単価は Event Functions の 1.5 倍(100 万リクエストあたり 0.30 ドルと 0.20 ドル)ですが、それを含めても安くなりました。
③ は、1,769 MB にしても請求対象の実行時間はほとんど変わらず(265.2 秒と 258.4 秒)、メモリを約 7 倍にした分がそのまま料金に加わりました。① と ② の差は、主に単価の差(Arm の単価は x86 の 0.8 倍)によるものです。
一方で、処理のほとんどが CPU を使う時間だったり、リクエストがまばらで実行環境に集められなかったりすると、この差は小さくなると考えられます(今回は未計測)。
④ の行は、負荷を処理した 3 個の実行環境の 30 秒間だけを数えています。負荷の前後に実行環境が残っていた時間の料金は、6 章で扱います。
5. 速いか
起動済みの状態では、応答時間の中央値は 4 つの構成とも 154〜175 ms で、④ Web Functions と ② Event Functions(Node.js・256 MB)の差は 10 ms でした。コールドスタートの 1 本目は ② だけ約 1.8 秒かかり、メモリを 1,769 MB に増やして実行環境を作り直した直後の ③ では 0.6〜0.9 秒でした。
応答時間は持続負荷のときの値で、200 が返ったリクエストだけで計算しています(判定数と 429 の数は付録 B.4)。コールドスタートの 1 本目は、35 分空けてから送った 1 本を 3 回測った範囲です。
| 構成 | 中央値 | 95 パーセンタイル | コールドスタートの 1 本目 | 続けて送った 2・3 本目 |
|---|---|---|---|---|
| ① Event Functions(Python・256 MB) | 175 ms | 218 ms | 781〜846 ms | 158〜237 ms |
| ② Event Functions(Node.js・256 MB) | 166 ms | 209 ms | 1,752〜1,892 ms | 314〜439 ms(1 本は別の実行環境に振り分けられ 1,248 ms) |
| ③ Event Functions(Node.js・1,769 MB)※ | 154 ms | 178 ms | 592〜890 ms | 156〜242 ms |
| ④ Web Functions | 156 ms | 196 ms | 825〜944 ms | 154〜214 ms |
※ ③ のコールドスタートは、35 分空けたものではありません。メモリの設定を 1,769 MB と 1,770 MB で切り替えて実行環境を作り直した直後の 1 本目です。

図 3: コールドスタートの 1 本目の内訳(3 回の平均)。② だけ、初期化の後の関数内の処理が長い
応答時間のほとんどは、関数の中から Jev を呼んでいる時間(持続負荷の中央値で 131〜150 ms)で、起動済みの状態では 4 つの構成の差は 20 ms ほどでした。コールドスタートの 1 本目を初期化と関数内の処理に分け、関数内の処理のうち Jev の呼び出しが占める時間を見ると(図 3、数値は付録 B.5)、② が遅いのは初期化ではなく、初期化の後の関数内の処理でした。同じ 256 MB の ① では、関数内の処理と Jev の呼び出しの差は 3〜4 ms です。③ にすると、初期化の時間は変わらないまま、関数内の処理が 278〜334 ms に短くなりました。
2 章のとおり、Event Functions はメモリに比例して CPU が割り当てられ、1,769 MB で 1 vCPU 相当です5。
256 MB では割り当てられる CPU が 1 vCPU の約 15% なので、② の 1 本目でプロセスが使った 61〜77 ms の CPU 時間は、実時間で約 0.5 秒に引き延ばされると考えられます。ただしこれで説明できるのは余分な約 1 秒の半分程度です。同じ 256 MB の ① では 1 本目が遅くなっていないので、Jev への最初の HTTPS 接続(DNS 解決や TLS ハンドシェイク)など、Node.js 固有の処理が関わっている可能性があります(要追加検証)。
④ Web Functions は、3.2 章のとおり 1 つの実行環境に vCPU 2 個が上限として割り当てられ、CPU は使った時間だけ課金されます26。
そのため、速さのためにメモリを多く設定して CPU を確保する、という Event Functions での調整(③)は ④ では不要で、4 章で見た約 5 倍の料金もかかりません。
6. 何に気をつけるか
④ Web Functions の料金は、リクエストの届き方で変わります。今回の計測では、送り続けるほど少ない実行環境に集まり、一度にまとめて送ると、実行環境の初期化と、途絶えたあとに残る時間の分が加わりました。
6.1. 送り続けると実行環境は減っていく
/whoami?sleep_ms=150(Jev の応答待ちに近い 150 ms だけ待つ)に、同時 20 本と 50 本を 2 分間送り続け、処理していた実行環境の数を 5 秒ごとに数えました(数え方は付録 B.3)。

図 4: 送り続けたときに処理していた実行環境の数。同時 20 本・50 本とも、約 1 分ごとに 1〜2 個ずつ減った
同時 20 本では、最初の 3 個から約 1 分ごとに 1 個ずつ減り、100 秒以降は 1 個の実行環境が 20 本を同時に処理しました。同時 50 本も 5 個から 2 個まで減りました。その間も、10 秒ごとに見た応答時間の中央値は 163〜164 ms で、1 個の実行環境に集まっても変わっていません。振り分けの対象でなくなった実行環境はすぐに止まり(実行環境の稼働時間のメトリクス EnvironmentActiveTime に数えられない)、負荷を止めたあとは最後の 1 個だけが残りました。4 章の持続負荷(30 秒間)は、最初から最後まで 3 個の実行環境に振り分けられ、5 秒ごとの件数はどの実行環境も 78〜106 件で、減らずに終わりました。
公式ドキュメントには、使用率の低い実行環境は、新しいリクエストの振り分けを止めてから取り除くと書かれています13。
6.2. まとめて届くと実行環境が増え、途絶えたあとも約 5〜7 分残る
/whoami?sleep_ms=1000 に同時 1〜200 本を一度に送ると、実行環境 1 個あたりの同時処理数は 2〜6 本までで、実行環境の数のほうが増えました(同時 10 本で 5 個、200 本で 65 個。7 回送り終えた時点の稼働中の実行環境数は最大 81 個。本数ごとの表は付録 B.2)。Lambda は実行環境 1 個あたりの同時処理数の上限を使用状況に応じて決め、小さな増加でコールドスタートを起こさないように、需要より先に実行環境を増やして余裕を持たせると書かれています13。
リクエストが途絶えたあと、最後の実行環境は約 5〜7 分残っていました。EnvironmentActiveTime のデータ点が途切れるまでの時間で見ています(時刻は日本時間)。
| きっかけ | 最後のリクエスト | データ点の最後 |
|---|---|---|
/whoami に同時 1〜200 本を 7 回 |
10/14 22:13 | 22:19 |
| 判定の持続負荷 | 22:41 | 22:47 |
| コールドスタート(1 回目) | 23:22 | 23:28 |
| コールドスタート(2 回目) | 23:57 | 10/15 0:03 |
| コールドスタート(3 回目) | 10/15 0:32 | 0:39 |
/whoami に同時 20 本を 2 分 |
8:33 | 8:38 |
実行環境が残る時間は保証されず、リクエストが無ければ実行環境はゼロになると書かれています10。上の時間は今回の観測です。
この間もメモリは課金されます。同時 1〜200 本を 7 回送ったあとは、81 個の実行環境の稼働時間が合計で約 29,000 秒になり、平均の消費メモリ(約 0.158 GB、付録 A.2)で約 4,600 GB 秒、約 0.02 ドルでした。実行環境を作るたびにかかる初期化の CPU(Web Functions のシステムログ platform.initReport の totalCpuTimeMs で 1 回約 220 ms、81 個で約 18 秒、約 0.0006 ドル)を足しても約 0.02 ドルです。7 回で送ったのは合計 518 リクエストです。4 章の持続負荷は 1,821 判定で 0.00098 ドルだったので、本数は少ないのに料金は約 0.02 ドルと大きくなりました。実行環境 1 個が 6 分残った場合は、消費メモリ 160〜267 MB で約 0.0002〜0.0004 ドルです。
一度にまとまって届き、そのあと途絶えるようなリクエストでは、作られた実行環境の初期化と残っている時間の分が料金の大半になると考えられます。
6.3. 見積もりと実行環境の数の上限
自分のアプリで見積もるときは、リクエスト数・vCPU の稼働時間・消費メモリ × 実行環境の稼働時間の 3 つをそれぞれ単価に掛けて足します。今回の課金対象の量は、Cost Explorer の使用量と一致しました(式と照合は付録 A)。持続負荷の 1 万判定あたりの料金だけで見積もると、実際より小さく出る可能性があります。6.2 章のように、実行環境が増える回数と残る時間も入れておくほうがよいと考えられます。
実行環境の数の上限は、エンドポイントの maxEnvironments(2〜10,000)で決められ、小さい値にすると実行環境の費用を抑えられると書かれています13。
7. まとめ
1.2 章の検証ゴールに対する結果です。
| # | 確かめたこと | 結果 |
|---|---|---|
| 1 | 入口のファイルを変えるだけで動くか | 動いた。OAC 越しの POST に x-amz-content-sha256 が不要になった |
| 2 | 安くなるか | 1 万判定あたり ④ Web Functions 約 0.0054 ドル、② Event Functions(Node.js・256 MB)約 0.0071 ドル、③ Event Functions(Node.js・1,769 MB)約 0.034 ドル |
| 3 | 速いか | 起動済みの状態では 4 つの構成とも中央値 154〜175 ms。コールドスタートの 1 本目は ② だけ約 1.8 秒 |
| 4 | 届き方で何が変わるか | 同時 20 本を送り続けると実行環境は 3 個から 1 個に減り、同時 200 本を一度に送ると 65 個に増えた(7 回の累計で 81 個)。途絶えたあとも最後の実行環境が約 5〜7 分残り、その間のメモリが課金された |
待ち時間がほとんどを占めるアプリでは、④ Web Functions は ② Event Functions(Node.js・256 MB)より安く、応答時間の中央値は ③ Event Functions(Node.js・1,769 MB)と同程度でした。一方で、料金はリクエストの届き方で変わります。一度にまとまって届く処理では、実行環境が増えることと、途絶えたあとも約 5〜7 分残ることを見積もりに入れておきます。
付録 A. 料金の計算式と Cost Explorer での照合
A.1. 計算式
Lambda の料金計算は 1 GB = 1,024 MB で数えます2。単価は東京リージョンのもので、AWS の Pricing API で取得しました。vCPU の稼働時間と実行環境の稼働時間は、CloudWatch メトリクスの EnvironmentCPUTime と EnvironmentActiveTime です(付録 B.1)。
Web Functions:
リクエスト数 × 0.0000003 ドル
+ vCPU の稼働時間(秒)× 0.0000322421 ドル
+ 消費メモリ(GB)× 実行環境の稼働時間(秒)× 0.0000042688 ドル
Event Functions:
リクエスト数 × 0.0000002 ドル
+ 請求対象の実行時間(秒)× 設定したメモリ(GB)× 0.0000166667 ドル(x86)または 0.0000133334 ドル(Arm)
4 章の表の各行は、次の計算です。
| 構成 | 計算 |
|---|---|
| ① Event Functions(Python・256 MB) | 263.0 秒 × 0.25 GB × 0.0000166667 ドル + 1,632 × 0.0000002 ドル |
| ② Event Functions(Node.js・256 MB) | 265.2 秒 × 0.25 GB × 0.0000133334 ドル + 1,738 × 0.0000002 ドル |
| ③ Event Functions(Node.js・1,769 MB) | 258.4 秒 × 1.728 GB × 0.0000133334 ドル + 1,858 × 0.0000002 ドル |
| ④ Web Functions | 10.4 秒 × 0.0000322421 ドル + 23.6 GB 秒 × 0.0000042688 ドル + 1,821 × 0.0000003 ドル |
④ の消費メモリは、負荷中の EnvironmentMaxMemoryUsage(1 分ごとの平均で 261〜265 MB)の最大値 267 MB を使いました。内訳はリクエスト料金が約 56%、vCPU が約 34%、メモリが約 10% でした。
A.2. Cost Explorer の使用量での照合
4 章と 6 章の計算はメトリクスからの見積もりなので、Cost Explorer の使用量と突き合わせました。Cost Explorer には、日本時間の 10 月 14 日 9 時から 15 日 6 時ごろまでの分が反映されていました。6.2 章の一度に送る計測、4 章の持続負荷、5 章のコールドスタートはこの範囲に入ります。6.1 章の送り続ける計測(10/15 8:33)は範囲外です。メトリクスも同じ範囲で合計しました。
| 使用タイプ | Cost Explorer の使用量 | 同じ範囲のメトリクス |
|---|---|---|
APN1-Lambda-Web-vCPU-Second-ARM |
86.09 vCPU 秒 |
EnvironmentCPUTime の合計 86,090 ms(86.09 秒) |
APN1-Lambda-Web-Request-ARM |
2,363 リクエスト |
ExecutedRequests の合計 2,363 |
APN1-Lambda-Web-Memory-GB-Second-ARM |
4,938.2 GB 秒 |
EnvironmentActiveTime の合計 31,244 秒 |
vCPU とリクエストは、メトリクスの値と一致しました。メモリの 4,938.2 GB 秒を稼働時間 31,244 秒で割ると約 0.158 GB(約 162 MB)です。同じ範囲の EnvironmentMaxMemoryUsage の平均(稼働時間で重み付けして約 159 MB)との差は約 3 MB で、消費メモリ × 実行環境の稼働時間で課金されていることを確かめられました。この範囲の稼働時間の 9 割以上は、6.2 章で一度に送ったあとに実行環境が残っていた時間です。リクエストの合間やアイドルの時間も課金の対象に入っていて、2 GB で数えると約 62,500 GB 秒で、Cost Explorer の値の約 13 倍になります。
Cost Explorer から出した約 162 MB が 4 章の 267 MB より小さいのは、大半を占めるアイドル中の実行環境の消費メモリが 145〜183 MB だったためです。負荷を処理していた実行環境は 261〜265 MB だったので、4 章の計算はそのままにしています。
Cost Explorer の金額は、Event Functions・Web Functions とも 0 ドルと表示されていました(推定値)。Web Functions の使用量に無料利用枠が適用されるかは、料金ページの記述からは確認できていません2。
付録 B. 計測の詳細
B.1. 計測の手順
4 種類の計測を行いました。
| 計測 | 中身 | Jev を呼ぶか |
|---|---|---|
| 同時処理(一度に送る) |
/whoami?sleep_ms=1000(1 秒待ってから実行環境の ID を返す)に、同時に N 本を 1 回送る |
呼ばない |
| 同時処理(送り続ける) |
/whoami?sleep_ms=150 に、同時 20 本・50 本を 2 分間送り続ける |
呼ばない |
| 持続負荷 | サービス名 1 つの判定を、同時 10 本で 30 秒間送り続ける | 呼ぶ |
| コールドスタート | 35 分空けてから 1 本、続けて 2 本。これを 3 回 | 呼ぶ |
持続負荷は 4 つの構成を 1 つずつ順番に実行しました。Event Functions は、アカウントの同時実行数の上限による 429 が返ってもそのまま続け、件数だけを記録しています(この 429 は Jev まで届いていません)。
料金の計算に使った課金対象の量は、次の場所から取りました。
| 関数の種類 | 課金対象 | 取り出し元 |
|---|---|---|
| Event Functions | 請求対象の実行時間 × メモリ、リクエスト数 | CloudWatch Logs の REPORT 行の Billed Duration
|
| Web Functions | vCPU の稼働時間、消費メモリ × 実行環境の稼働時間、リクエスト数 | CloudWatch メトリクス(名前空間 AWS/Lambda/Web)の EnvironmentCPUTime・EnvironmentActiveTime・EnvironmentMaxMemoryUsage14
|
Web Functions のログ(ロググループ /aws/lambda/web/<関数名>)には REPORT 行が無く、代わりに JSON のシステムログ(platform.initReport など)が出ます14。
B.2. 一度に送ったときの実行環境の数
/whoami?sleep_ms=1000 に同時に N 本を 1 回送り、応答に含まれる env_id の種類と inflight の最大値を数えました。N を 1 から 200 まで、3 秒ずつ空けて約 30 秒の間に 7 回送っています。64 本と 65 本は、リビジョンの設定 maxConcurrencyPerEnvironment(デフォルトの 64 のまま)をまたぐ本数として入れました。
| 同時の本数 | ④ Web Functions の実行環境の数 | ④ Web Functions の実行環境 1 個あたりの同時処理数(最大) | ② Event Functions(Node.js・256 MB)の実行環境の数 |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 10 | 5 | 2 | 10 |
| 50 | 25 | 2 | 10(残り 40 本は 429) |
| 64 | 36 | 2 | (未計測) |
| 65 | 46 | 2 | (未計測) |
| 128 | 54 | 5 | (未計測) |
| 200 | 65 | 6 | (未計測) |
7 回を送り終えた時点で、メトリクスの稼働中の実行環境数(EndpointActiveEnvironments)は最大 81 個でした(200 本の回の応答に現れたのは 65 個)。
B.3. 送り続けたときの実行環境の数
6.1 章の計測では、5 秒ごとに、その区間のリクエストの 5% 以上を処理した実行環境を数えました(切り替わりの区間で数件だけ処理した実行環境は数えません)。応答時間の中央値は 10 秒ごとに計算しています。
| 送り続けた本数 | 1 段階目(時間帯: 実行環境の数) | 2 段階目 | 3 段階目 |
|---|---|---|---|
| 同時 20 本 | 0〜35 秒台: 3 個(1 個で最大 7〜10 本) | 40〜95 秒台: 2 個(最大 10 本) | 100 秒〜: 1 個(最大 20 本) |
| 同時 50 本 | 0〜30 秒台: 5 個(最大 10〜18 本) | 35〜90 秒台: 3 個(最大 17〜25 本) | 95 秒〜: 2 個(最大 25 本) |
持続負荷(判定を同時 10 本で 30 秒間)では、最初から最後まで 3 個の実行環境に振り分けられ、5 秒ごとの件数はどの実行環境も 78〜106 件でした(実行環境 1 個あたりの同時処理数は最大 5、中央値 3)。
B.4. 持続負荷の判定数と Jev 呼び出しの所要時間
持続負荷で返った件数と、関数の中で測った Jev の所要時間です。
| 構成 | 送った本数 | 200 | 429 | Jev 呼び出しの所要時間(中央値) |
|---|---|---|---|---|
| ① Event Functions(Python・256 MB) | 1,632 | 1,632 | 0 | 150 ms |
| ② Event Functions(Node.js・256 MB) | 1,794 | 1,738 | 56 | 141 ms |
| ③ Event Functions(Node.js・1,769 MB) | 1,858 | 1,858 | 0 | 131 ms |
| ④ Web Functions | 1,821 | 1,821 | 0 | 140 ms |
「Jev 呼び出しの所要時間」は、関数の中で Jev への fetch を囲んで測った時間です。② Event Functions(Node.js・256 MB)の 429 は、2 章のアカウントの同時実行数の上限によるものです(ConcurrentInvocationLimitExceeded)。同じ上限を使う ① Event Functions(Python・256 MB)では 429 が出ておらず、この差の理由は確かめていません。
B.5. コールドスタートの 1 本目の内訳
35 分空けてから送った 1 本目を、ログを使って内訳に分けました。3 回の範囲を載せます(図 3 はこの 3 回の平均)。
| 構成 | 手元で測った 1 本目 | Lambda の初期化 | 関数内の処理 | うち Jev 呼び出しの所要時間 |
|---|---|---|---|---|
| ① Event Functions(Python・256 MB) | 781〜846 ms | 117〜142 ms | 337〜347 ms | 334〜343 ms |
| ② Event Functions(Node.js・256 MB) | 1,752〜1,892 ms | 176〜206 ms | 1,274〜1,428 ms | 560〜620 ms |
| ③ Event Functions(Node.js・1,769 MB)※ | 592〜890 ms | 154〜208 ms | 278〜334 ms | 187〜213 ms |
| ④ Web Functions | 825〜944 ms | 311〜405 ms | (REPORT 行が無く、関数内の処理の時間は取れない) |
176〜202 ms |
※ ③ の行は、5 章と同じく、メモリの設定を切り替えて実行環境を作り直した直後の 1 本目です。
初期化は、Event Functions が REPORT 行の Init Duration、Web Functions が platform.initReport の totalDurationMs です。手元で測った 1 本目から初期化と関数内の処理を引いた残り(CloudFront と通信の分)は、256 MB の 2 構成では 260〜390 ms、1,769 MB では 160〜440 ms でした。② の 1 本目でプロセスが使った CPU 時間は 61〜77 ms でした。
参考
-
AWS Lambda が Lambda Web Function を発表(AWS What's New、2026-10-12。発表時点のランタイムは Node.js。既存の Lambda 関数を Lambda Event Functions に改名。本文の引用は英語版から) ↩ ↩2 ↩3
-
AWS Lambda の料金(Web Functions はリクエスト数・vCPU の稼働時間・消費メモリで課金。メモリはリクエストの合間も含めて実行環境が動いている間課金。計算例は 1 GB = 1,024 MB。日本語版は 2026-10-15 時点で Web Functions の記述が無いため英語版) ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
TypeSafe AI Docs: Quickstart(Jev のエンドポイント
POST /v1/systemone、modeljev-latest) ↩ -
AWS Lambda Web Functions × Hono - アダプター不要のサーバーレスWeb開発(Zenn、RUI さん、2026-10-13。Event Functions を 2,048 MB にそろえて比較) ↩
-
Lambda 関数のメモリを設定(AWS 公式。メモリに比例して CPU が割り当てられ、1,769 MB で 1 vCPU 相当) ↩ ↩2
-
Lambda quotas(AWS 公式。新しいアカウントは上限が低く設定され自動で引き上げられる。Web Functions は実行環境あたりメモリ 2 GB・vCPU 2、タイムアウトのデフォルト 30 秒、Arm の vCPU のデフォルト 2,000。日本語版は 2026-10-15 時点で Web Functions の記述が無いため英語版) ↩ ↩2 ↩3 ↩4 ↩5
-
Lambda 関数のスケーリングについて(AWS 公式。アカウントの同時実行数の上限はデフォルトで 1,000) ↩
-
Lambda Web Function runtimes(AWS 公式。待ち受け先は
AWS_LAMBDA_HTTP_ENDPOINTのhost:port。2026-10-15 時点で英語版のみ) ↩ -
Creating a Lambda Web Function(AWS 公式。
aws lambda-web deploy、入口のAWS_LAMBDA_NODEJS_ENTRYPOINT。2026-10-15 時点で英語版のみ) ↩ ↩2 -
Execution environment lifecycle(AWS 公式。起動から 10 秒以内に待ち受け、残る時間は保証されない、リクエストが無ければゼロになる、リクエストごとの値をグローバル変数に置かない。2026-10-15 時点で英語版のみ) ↩ ↩2 ↩3
-
Restrict access to an AWS Lambda Web Function origin(AWS 公式。署名動作は
always-amz-authのみ、本文はUNSIGNED-PAYLOADで署名。2026-10-15 時点で英語版のみ) ↩ ↩2 -
AWS Lambda 関数 URL オリジンへのアクセスを制限する(AWS 公式。PUT・POST では本文の SHA-256 を
x-amz-content-sha256に入れる必要がある) ↩ -
Scaling behavior for Lambda Web Functions(AWS 公式。実行環境 1 個あたりの同時処理数の上限は Lambda が決める。需要より先に実行環境を増やして余裕を持たせ、使用率の低い実行環境は取り除く。
maxEnvironments。2026-10-15 時点で英語版のみ) ↩ ↩2 ↩3 -
Using CloudWatch metrics with Lambda Web Functions(AWS 公式。
EnvironmentActiveTime・EnvironmentCPUTimeなど。2026-10-15 時点で英語版のみ) ↩ ↩2