何も動いていないのに時間で課金される
- 時間課金される
- GB課金されない
- 個数課金されない
ひとことで言うと
時間メーターが測るのは活動ではなく存在。止める手段は削除だけで、「停止」はたいてい削除ではない。
なぜそうなるのか
時間メーターの判定条件は1つしかない。しかもそれは、多くの人が当てている条件ではない。条件は「それは存在しているか」であって、「それは何かしているか」ではない。
これは AWS の課金でいちばん繰り返される驚きで、しかも AWS はこれを一度も原則として書いていない。書かれるのは常にサービス単位の脚注で、しかも各サービスの語彙で書かれる。エンドポイント、インデックス、サブネットの関連付け、プロビジョンドモデルユニット、最小 ACU。料金ページを1枚ずつ読むと脚注が40個集まる。中身は全部同じ脚注だ。
仕組み自体は不思議でもなんでもない。何かをプロビジョンすると、AWS はその容量を自分のために確保して、他の誰にも売らなくなる。その確保こそが商品であって、そこに仕事を投げるかどうかは別の行為だ。メーターにはそれを気にする理由がない。誰も使っていない請求書を支配するのが時間メーターなのはこれが理由で、残り2つ — GB と個数 — は「こちらが何かする」ことを必要とするのに対し、時間だけは「過去に一度何かした」ことしか必要としない。
見分け方は簡単で、時間課金と回数課金の両方を載せている料金ページが怪しい。DynamoDB は1つのサービスの中に両方が入っている稀な例だ。プロビジョンドキャパシティモードなら、設定した RCU / WCU はトラフィックゼロでも毎時間課金され、メーターは時間。同じテーブルをオンデマンドに切り替えると、まったく同じクエリが1回いくらで課金され、メーターは個数になる。データも使い方も変わっていない。変えたのは「何をしたか」ではなく「何を買ったか」だ。
そして、人が同義語だと思っていて AWS は同義語だと思っていない動詞が3つある。
- 停止 (stop) — たいていメーターを1本黙らせて、残りは回したままにする。3つの中で一番弱いのに、みんな最初にこれに手を伸ばす。
- 一時停止 (pause) — 本物だが、明示的に実装しているサービスにしか存在せず、しかも課金の一部にしか効かないことがある。
- 削除 (delete) — どこでも効く唯一の動詞。ただし、このページの最後に出てくる例外を除く。そこには削除する対象そのものがない。
で、いくらなの
以下はすべて us-east-1 のオンデマンド、そしてすべてリクエスト0件で発生する。月額は730時間で計算した。
- Lambda のプロビジョンドコンカレンシー — $0.015 / GB-hour。AWS の料金ページはこの区間を珍しくはっきり書いている。「有効にした時点から無効にするまでで計算し、5分単位に切り上げる」。この文に呼び出し回数は出てこない。1GB の関数に10個分確保しておくと、誰も呼ばなくても月およそ $110。しかも Lambda の無料枠はプロビジョンドコンカレンシーには一切適用されない。
- Bedrock の Provisioned Throughput — 買うのはモデルユニットで、API リファレンスは「課金は時間単位で発生し、コミット期間が長いほど割引される」と書いている。効いているのは commitment という単語のほうだ。1ヶ月や6ヶ月のコミットは「すでに買うと約束した時間の塊」なので、そもそも逃げ込める遊休状態が存在しない。一部のベースモデルにはコミットなしの Provisioned Throughput もあり、そちらは解放できる。
- App Runner — メモリが $0.007 / GB-hour、vCPU が $0.064 / vCPU-hour。この2つは発火条件が違う。「アプリケーションがデプロイされている間、各コンテナインスタンスにプロビジョンされたメモリに対して課金される」。vCPU が回るのは実際にリクエストを処理している間だけ。2GB のサービスを1ヶ月誰にも使わせないと約 $10。額は小さいが、ゼロにはならない。App Runner にスケール・トゥ・ゼロはないからだ。用意されているレバーは
PauseServiceAPI で、これは「サービスのコンピュートキャパシティをゼロに落とす」。 - Aurora Serverless v2 — $0.12 / ACU-hour を、設定した最小 ACU に対して秒単位で課金する。クエリが1本も来なくてもだ。最小 0.5 ACU なら、空のデータベースが月およそ $44。最小を 0 にするのは端数の話ではなく機能スイッチで、0 にして初めて
SecondsUntilAutoPauseが現れ、300秒から1日までの間で選んだ待ち時間のあとにクラスタが自動停止する。RDS の API リファレンスは、このプロパティが「クラスタの最小キャパシティが 0 ACU に設定されているときにのみ表示される」と明記している。 - Client VPN — 「エンドポイントの関連付けごと、および VPN 接続ごとに時間単位で課金される」。前半の関連付け側は関連付けたサブネット1つにつき $0.10 / 時で、接続ユーザー数とは無関係。AWS 自身の試算例が、2サブネットを24時間回して月 $144、まだ誰も接続していない状態で、と書いている。エンドポイントの ENI は使用中パブリック IPv4 としても課金される。
- パブリック IPv4 — 2024年2月1日から $0.005 / アドレス / 時。VPC の料金ページは「使用中」と「アイドル」に同じレートを並べている。効いてくる違いは停止したときの挙動のほうだ。EC2 は「インスタンスが停止・休止・終了したときにパブリック IP アドレスを解放する」ので、自動割り当てのアドレスは課金が止まる。Elastic IP はインスタンスではなくアカウントに紐づくので、リリースするまで同じ $0.005 を刻み続ける。放置1個あたり月およそ $3.65。
- EBS — 「すべての EBS ボリュームタイプのストレージは、ストレージを解放するまで、プロビジョンした GB 数に対して月単位で課金される」。使った量ではなくプロビジョンした量。典型例は停止したインスタンスが置き去りにしたボリュームで、EC2 の API ドキュメント自身が、インスタンスを停止しても「ルートパーティションの EBS ボリュームは残り、EBS ボリューム使用料が課金される」と書いている。500GB の gp3 が $0.08 / GB-month なら月 $40。3月から電源が入っていないインスタンスにぶら下がったまま。
- Kendra — この主題について AWS が書いたいちばん明快な一文。「インデックスを作成すると、そのインデックス内のストレージやクエリのキャパシティを一切使っていなくても課金が発生する」。続けて「課金を止めるにはインデックスを削除する」。GenAI Enterprise のベースインデックスは $0.32 / 時で、空のインデックスが月およそ $234。
- SageMaker のリアルタイムエンドポイント — 課金されるのはデプロイされていた時間で、作成から削除までが区間になる。SageMaker のデベロッパーガイドは警告枠でこう書く。「エンドポイントはリクエストを処理していなくても課金され続ける。すべての課金を止めるにはエンドポイントを削除しなければならない」。停止ボタンは存在しない。ゼロまで落ちるのは非同期推論とサーバーレス推論のほうだ。
- EMR / OpenSearch のクラスタ — EMR のドキュメントは、長時間稼働クラスタは「シャットダウンする操作を取るまで、動き続け、仕事を受け付け、課金を積み続ける」と書き、
WAITINGのまま放置されたクラスタは「終了させないと無限に走り続け、アカウントに課金を発生させる」とまで書いている。OpenSearch は「インスタンスが available な状態で動いている1時間ごと」に課金し、端数は1時間に切り上げる。どちらのメーターもクエリ数を読んでいない。 - ALB と NAT Gateway — 1バイトも流れていない状態で、ロードバランサが $0.0225 / 時、NAT Gateway が $0.045 / 時。それぞれ月およそ $16 と $33。この上にキャパシティ課金や GB 課金が乗る。もう誰もデプロイしていない開発環境のコピーの正体は、たいていこの2つだ。
- CodeBuild のリザーブドフリート — インスタンス時間は「新しいインスタンスをリクエストした時点から、そのインスタンスが終了するまでを分単位で計算する」、インスタンスあたり最低60分。課金開始はプロビジョニングであってビルド開始ではない。オンデマンドではなくリザーブドキャパシティを選んだとき、交換したのはまさにこれだ。
例外と罠
「停止」はサービスごとに意味が違う単語で、何の意味も持たないサービスもある。 EC2 の停止はインスタンスのメーターを落とすが、EBS と Elastic IP は回したままにする。Transfer Family は API リファレンスで言い切る。「サーバーを停止してもエンドポイントの課金は減らないし影響も受けない。課金を止めるにはサーバーを削除しなければならない」。MediaLive はさらに踏み込んで、遊休そのものに値段を付けている — ユーザーガイドは「動いていないチャネルごとに idle channel charge がある」と明記し、push input にも遊休料金がある。無料なのは遊休中の pull input だけだ。同じ「停止」ボタンに3通りの意味がある。
本当にゼロになるのは、ボタンではなく設定した下限のほうだ。 実際にゼロまで落ちるサービスは、こちらが最小値を 0 に設定し、待ち時間を指定したから落ちている。Aurora Serverless v2 の MinCapacity=0、SageMaker 非同期推論の最小キャパシティ 0、10分アイドルでゼロに落ちる OpenSearch NextGen サーバーレスコレクション。同じサーバーレスでも classic のコレクションは 2 OCU が下限で、落ちない。オフスイッチを探す前に、下限の設定項目を探すこと。
引っかけを見抜く「形」。 サービスの中身を理解しなくても、大半はこれで見つかる。料金ページや Cost Explorer の内訳で次の語を探す。per hour / per month / provisioned / reserved / minimum / floor / capacity / association / endpoint / cluster / subscription。usage type なら -Hours、Usage、GB-Mo で終わっているもの。そのうえで、全部をまとめて捕まえる質問を1つ投げる。
一週間トラフィックを送らなかったら、それでも請求されるのはどれか。
即座に「何もない」と答えられないものは時間メーターに乗っている。次に聞くことはいつも同じで、正確には何を削除すればいいのか、そして削除未満の手段で止まるのか。
そして、削除しても効かない場合がある。 ここがこの原則の正直な限界だ。Shield Advanced は月 $3,000 の固定費で「1年間のサブスクリプションコミットメントを必要とする」、しかも組織のペイヤーアカウント単位での課金。EKS Anywhere の Enterprise Subscription は1年契約でクラスタあたり $24,000、無償で解約できるのは「購入から最初の7日以内」だけ。保護対象のリソースを全部消しても、クラスタを全部消しても、この請求は1円も動かない。時間メーターは相変わらず存在を測っている — ただし存在しているのが契約で、契約には削除ボタンがない。これらを買った時点で、時間メーターの数ヶ月分を前払いで買っている。レバーが存在したのは、契約するかどうかを決めた瞬間だけだ。