AWS Lambdaは1ドルで何回動くのか、Bedrockは1円で何往復できるのか。理論値を計算した上で実際に回して数えてみました。日本語トークンの割高さも紹介します。
■ TL;DR
- $1でLambdaは 128MB×100ms なら約245万回、10GB×30秒なら約200回。ただし1万倍の差を生むのは設定ではなく「仕事の重さ」でした
- 実測では、何もしない関数が$1換算で約441万回(課金の88%はリクエスト料金)。3秒のCPU処理は約15.6万回で、メモリを128MB→1GBにしても料金は同じまま8倍速くなりました
- 1円(≒$0.00627)で、Nova Microなら実測135往復、Claude Sonnet 4.6は1往復目で1円を超えました。ここも100倍以上の差
- 同じ内容の文章でも、日本語は英語より入力トークンが1.75倍(Claude)〜1.3倍(Nova)増えます。「1円で買える文章量」は言語で変わります
- 結論:「安い」は感想、「1ドルで何回」は仕様。単位あたりで持つと設計の判断が速くなります
■ 目次
- はじめに — なぜ「1」で測るのか
- ルール決め:何を「1」とするか
- 前半:1ドルでLambdaはどこまで回るか
- 後半:1円でAIはどこまでしゃべるか
- 実測してみた(ここが本番)
- 使い分けの指針
- 後片付け
- まとめ
■ はじめに — なぜ「1」で測るのか
料金ページを見て「1GB-秒あたり$0.0000166667」と書かれていても、正直よく分からないんですよね。ゼロが多すぎて桁が滑ります。
「で、それって結局いくら使えるの?」——そう思って、逆から測ってみることにしました。1ドルを渡したらLambdaは何回動くのか。1円を渡したらAIは何回しゃべるのか。
単価は割り算、体感は掛け算です。料金表は「1回いくら」で書いてありますが、財布が痛むのは「何回やったか」を掛けた後。だったら最初から「固定の金額で何回」に直しておいたほうが、設計のときに頭が回ります。
■ ルール決め:何を「1」とするか
先に前提を固めます。ここを雑にすると数字が信用されないので。
|
項目 |
値 |
備考 |
|
リージョン |
us-east-1(バージニア北部) |
オンデマンド、Lambdaはx86_64 |
|
為替 |
1ドル = 159.4円 |
2026年8月末の為替 |
|
1円 |
≒ $0.00627 |
1 ÷ 159.4 |
|
無料枠 |
使い切った後として計算 |
無料枠の話は後で回収します |
|
「1往復」の定義 |
入力 約1,000トークン + 出力 最大300トークン |
社内チャットボット1回ぶんくらいの想定 |
|
単価の出典 |
AWS Price List API(2026-08-19/26版)+公式料金ページ |
Lambda: $0.0000166667/GB-秒, $0.20/100万リクエスト |
なぜLambdaは「1ドル」でAIは「1円」なのか。最初は両方1ドルで揃えるつもりでした。でも計算してみると、1ドルのLambdaは200万回以上で数えきれず、1円のAIはちょうど1往復くらい。粒度がまるで違うので、それぞれ「数えられる単位」に合わせました。これ自体がひとつの発見です。
■ 前半:1ドルでLambdaはどこまで回るか
Lambdaの課金は2本立てです。
料金 = リクエスト数 × $0.0000002
+ GB-秒 × $0.0000166667
GB-秒 = メモリ(GB) × 課金対象時間(秒)
1ドルをGB-秒に直すと 1 ÷ 0.0000166667 = 60,000 GB-秒。
リクエストだけなら 1 ÷ 0.0000002 = 500万リクエスト。
「1ドル = きっちり60,000 GB-秒 = 500万リクエスト」これは覚えやすいですね。
この式に設定を代入すると、こうなります。
|
メモリ × 実行時間 |
GB-秒/回 |
1回あたり |
1ドルで回せる回数 |
|
128MB × 100ms |
0.0125 |
$0.000000408 |
約245万回 |
|
512MB × 200ms |
0.1 |
$0.00000187 |
約54万回 |
|
1GB × 1秒 |
1.0 |
$0.0000169 |
約5.9万回 |
|
10GB × 30秒 |
300 |
$0.0050002 |
約200回 |
一番上と一番下で1万倍以上ブレます。
つまり「Lambdaは安い」ではなく、「Lambdaは自分で高くできる」が正確です。
……と、この時点では思っていました。実測でこれは半分ひっくり返ります。
たとえるなら電気代の「1kWh」です。
単価は一定でも、扇風機とエアコンで請求は全然違う。
Lambdaはメモリ設定がそのままCPU設定でもある(1,769MBで1vCPU相当)ので、「メモリを上げる」はワット数の高い機器に替えるような操作です。
同じ量の湯を沸かすなら早く終わって電気代は同じ、待ち時間ぶん回し続ければ高くなる。この「同じ仕事なら」の部分は後で実測します。
補足として、arm64(Graviton)はGB-秒単価が$0.0000133334で20%安いので、同じ1ドルで計算時間が1.25倍回ります。乗り換えるだけで25%長く回るわけです。
そして先に一度オチを言っておくと、Lambdaの無料枠(月100万リクエスト+40万GB-秒、期限なし)を金額に直すと $0.20 + $6.67 = 月$6.87 相当。
つまり個人検証だと、1ドルに到達させるほうが難しいです。
■ 後半:1円でAIはどこまでしゃべるか
Bedrockの課金は入力トークンと出力トークンの2本立て。
「1往復=入力1,000+出力300」で計算します。
|
モデル |
入力 / 出力 単価($ per 1M tok) |
1往復のコスト |
1円で |
|
Amazon Nova Micro |
$0.035 / $0.14 |
$0.000077 ≒ 0.012円 |
約81往復 |
|
Amazon Nova Lite |
$0.06 / $0.24 |
$0.000132 ≒ 0.021円 |
約48往復 |
|
Claude Haiku 4.5 |
$1 / $5 |
$0.0025 ≒ 0.40円 |
約2.5往復 |
|
Claude Sonnet 4.6 |
$3 / $15 |
$0.0075 ≒ 1.20円 |
0.8往復(届かない) |
|
Claude Opus 4.8 |
$5 / $25 |
$0.0125 ≒ 1.99円 |
約0.5往復 |
1円でSonnetは1往復できません。
これがこの記事で一番言いたかった数字です。Nova Microとの差は約100倍。(実測では Nova Micro が135往復したのに対し、Sonnet は1往復も届きませんでした。後述します。)
Lambdaの「メモリ設定」に相当するのが、AIでは「モデルの選択」です。
いくつか補足を。
- 出力は入力の3〜5倍高い。生成は1トークンずつ順番に計算するので、読むより書くほうが重いためです。タクシーで言えば、入力=乗る前に行き先を説明する時間、出力=実際に走った距離。距離のほうが高い
- 拡張思考(extended thinking)のトークンは出力として課金されます。「考えている時間もお金」です。今回はthinkingを使っていません
- そもそも1トークンとは:英語で約4文字・0.75語。日本語は1〜2文字で1トークンくらいの挙動です(後で実測します)
- 入力 1,000 トークン ≒ 約 1,200 文字(Claude の日本語は 1 文字約 0.83 トークン)
- 出力 300 トークン ≒ 約 360 文字
- つまり「A4 半ページぶんくらいを読ませて、200〜300 字で答えさせる」1 ターンです。
■ 実測してみた
① Lambdaを1万回叩いて1ドルに外挿する
245万回は現実的に回せません(回せなくはないですが、検証のために1ドル使うのに何時間もかかります)。なので1万回の実測値から1ドルに外挿する方法にしました。
用意したのは、何もしない128MBのPython関数です。
def handler(event, context):
return {"ok": True}
これをLogType="Tail"付きで並列invokeし、レスポンスに含まれるREPORT行からDuration・Billed Duration・Init Durationを拾って集計します。CloudWatch Logsを後から漁るより、この方法だと1回ごとの課金時間がその場で取れます。
import boto3, base64, re
from concurrent.futures import ThreadPoolExecutor
lam = boto3.client("lambda", region_name="us-east-1")
REPORT = re.compile(
r"Duration: ([\d.]+) ms\s+Billed Duration: (\d+) ms"
r"\s+Memory Size: (\d+) MB\s+Max Memory Used: (\d+) MB"
r"(?:\s+Init Duration: ([\d.]+) ms)?"
)
def one(_):
r = lam.invoke(FunctionName="one-dollar-lambda", LogType="Tail", Payload=b"{}")
m = REPORT.search(base64.b64decode(r["LogResult"]).decode())
return float(m.group(1)), int(m.group(2)), m.group(5) # 実時間, 課金時間, コールドならInit時間
with ThreadPoolExecutor(50) as ex:
rows = list(ex.map(one, range(10000)))
……と書いたのですが、このスクリプトは動きませんでした。正確には動いたけれど遅すぎました。並列数を50にしても1回0.55秒ずつ直列に処理され、毎分110回程度。1万回に90分かかる計算で、しかもボトルネックは手元のPCからus-east-1までの回線でした。
なので「叩く側」もLambdaにしました。us-east-1内にone-dollar-invokerという関数を置き、1回の呼び出しで対象を200回invokeしてREPORT行を返す。それをローカルから50回並列に呼びます。
# one-dollar-invoker(叩く側)の中身。対象と同じリージョンで動かす
def handler(event, context):
with ThreadPoolExecutor(20) as ex:
rows = list(ex.map(one, range(event["n"]))) # one() は上と同じ
return {"rows": rows}
結果、1万回が28.7秒で終わりました。
|
項目 |
値 |
|
実行回数 |
10,000回(128MB, x86_64, python3.13) |
|
実時間 Duration |
平均 6.9ms/中央値 1.79ms/最大 56.8ms |
|
課金時間 Billed Duration |
平均 12.8ms/最小 1ms/最大 112ms |
|
コールドスタート |
662回(6.6%)、Init平均 80ms |
|
課金GB-秒(合計) |
15.96 GB-秒(実時間ベースだと 8.65) |
|
コンピュート料金 |
$0.000266 |
|
リクエスト料金 |
$0.002000 |
|
合計 |
$0.00227(≒0.36円) |
これを1ドルに外挿すると、こうなります。
|
基準 |
1回あたり |
1ドルで |
|
理論値(128MB × 100ms) |
$0.000000408 |
約245万回 |
|
理論値(128MB × 1ms、下限) |
$0.000000202 |
約495万回 |
|
実測(128MB × 平均12.8ms) |
$0.000000227 |
約441万回 |
見どころは3つあります。
1. 課金の88%はリクエスト料金だった。 何もしない関数だと計算時間が短すぎて、GB-秒より「1回$0.0000002」のほうが効きます。「軽い処理を大量に回す」ケースでは、メモリやアーキテクチャをいじる前に回数を減らすのが正解、というのが数字で出ました。
2. 課金時間は、実時間の1.84倍だった。 原因は2つあります。1つは1ms単位の切り上げで、中央値1.79msの処理が2msに切り上がるだけで10%以上の上乗せ。もう1つがコールドスタートのINIT課金で、こちらが大半です(次の3で詳しく)。「1ms単位課金」も「INIT課金」も、1ms級の処理では誤差ではありません。
3. コールドスタート6.6%が、課金時間の約4割を食っていた。 2025年8月からINIT(初期化)フェーズも課金対象になっているので、コールド1回は課金82.5ms、ウォーム1回は7.8ms。約10倍です。50バッチ×20並列(最大1,000並列)でどっと叩いたので6.6%は高めの数字ですが、「コールドは回数は少ないが1回が重い」構造は同じです。
小ネタをひとつ。叩く側のLambda(1GB × 合計298秒 ≒ 298 GB-秒 ≒ $0.005)のほうが、叩かれた側のコンピュート料金($0.00027)の18倍高かったです。測定器のほうが被測定物より高い。実測あるあるです(このあと出てくる重い処理では逆転します)。
念のためCloudWatchメトリクスとも突き合わせました。Invocationsの合計は10,056(1万回+動作確認ぶん)、Durationの平均は6.91msで、手元の集計(6.92ms)と一致。REPORT行から拾った数字はそのまま信用してよさそうです。
● 軽すぎたので、重い処理でも測った
ここまでの数字は「何もしない関数」のものです。
1.79msの処理で「リクエスト料金が88%」「課金時間が84%増し」と言われても、それは処理が軽すぎるから、という反論は当然あります。
なので固定量のCPU仕事(math.sqrtを150万回)をする関数を、128MBと1GBの2つ作って各1万回回しました。Lambdaはメモリ設定に比例してCPUが割り当てられるので、「メモリを上げると速く終わる」も同時に確かめられます。
|
|
128MB |
1GB(1,024MB) |
|
実時間 Duration 中央値 |
2,981ms |
364ms(8.2倍速い) |
|
課金時間 Billed Duration 平均 |
2,983ms |
375ms |
|
コールドスタート |
849回(8.5%) |
827回(8.3%) |
|
課金GB-秒(1万回) |
3,729 |
3,748 |
|
コンピュート料金 |
$0.0621 |
$0.0625 |
|
リクエスト料金 |
$0.0020 |
$0.0020 |
|
合計 |
$0.0641(≒10.2円) |
$0.0645(≒10.3円) |
|
1ドルで |
約15.6万回 |
約15.5万回 |
3つの見どころは、重い処理だとこう変わります。
1. リクエスト料金は88% → 3%に。
主役がGB-秒に交代しました。同じ「何回回せるか」でも、軽い処理と重い処理では節約すべき場所がまったく違うということです。
2. 切り上げとコールドスタートは誤差になった。
3秒の処理に1msの切り上げは最大でも0.03%、Initの80msも 80ms × 849回 ÷ 全課金時間 で0.2%程度です。1GB側でも切り上げは0.3%以下、Initが1.8%。何もしない関数では合計84%増しだったものが、合わせても2%以下に収まりました。「1ms課金」「INIT課金」を気にする価値があるのは、処理が数十ms以下のときだけです。
3. メモリを8倍にしたら、8.2倍速くなって、料金は同じだった。
これが一番の収穫です。128MBで3秒かかる仕事は、1GBだと0.36秒。GB-秒は 0.125GB × 2.98s = 0.373 と 1GB × 0.375s = 0.375 でほぼ一致します。CPUバウンドな処理なら、メモリを上げても料金は変わらず、ユーザーの待ち時間だけが8分の1になる。「メモリは小さいほど安い」は、少なくともこの種の処理では間違いでした(I/O待ちが多い処理は速くならないので話が変わります。要実測)。
なお128MB側は1回3秒×並列1,000でアカウントの同時実行上限(1,000)に当たり、338回スロットルされました。スロットルは課金されず、SDKのリトライで1万回きっちり完走しています。「重い処理を大量に並べると、料金より先に同時実行数にぶつかる」も、やってみて分かることでした。
つまり3章の表の「128MB×100ms=245万回」と「10GB×30秒=200回」は、同じ仕事を違う設定で回した結果ではなく、違う仕事の話です。
同じ仕事なら、設定を変えても料金はそれほど動かない。動かすのは仕事の量そのものです。
② 1円ぶんのAIに実際に仕事をさせる
同じプロンプトを5モデルに投げます。
中身は「社内クラウド利用ガイドラインの抜粋(約1,000字)を新入社員向けに200字で要約して、重要ポイントを3つ挙げて」というもの。
maxTokens=300で出力を頭打ちにしています。
br = boto3.client("bedrock-runtime", region_name="us-east-1")
r = br.converse(
modelId="us.anthropic.claude-sonnet-4-6",
messages=[{"role": "user", "content": [{"text": PROMPT_JA}]}],
inferenceConfig={"maxTokens": 300},
)
print(r["usage"])
返ってきたusageを生のまま貼ります。
nova-micro {'inputTokens': 581, 'outputTokens': 161, 'totalTokens': 742}
nova-lite {'inputTokens': 581, 'outputTokens': 280, 'totalTokens': 861}
haiku-4.5 {'inputTokens': 862, 'outputTokens': 300, 'totalTokens': 1162, 'cacheReadInputTokens': 0, 'cacheWriteInputTokens': 0}
sonnet-4.6 {'inputTokens': 862, 'outputTokens': 276, 'totalTokens': 1138, 'cacheReadInputTokens': 0, 'cacheWriteInputTokens': 0}
opus-4.8 {'inputTokens': 888, 'outputTokens': 300, 'totalTokens': 1188, 'cacheReadInputTokens': 0}
ここで早速ひとつ気づきがあります。同じプロンプトなのに、Novaは581トークン、Claudeは862トークンと数えています。トークナイザがモデルごとに違うので、「1,000トークンのプロンプト」という前提自体がモデル依存でした。ルール決めの段階では思い至らなかったところです。
料金に直すとこうなります。
|
モデル |
実入力 / 実出力 tok |
実コスト |
1円で |
|
Nova Micro |
581 / 161 |
$0.000043 ≒ 0.0068円 |
約146往復 |
|
Nova Lite |
581 / 280 |
$0.000102 ≒ 0.016円 |
約61往復 |
|
Claude Haiku 4.5 |
862 / 300 |
$0.00236 ≒ 0.38円 |
約2.7往復 |
|
Claude Sonnet 4.6 |
862 / 276 |
$0.00673 ≒ 1.07円 |
0.9往復(届かない) |
|
Claude Opus 4.8 |
888 / 300 |
$0.0119 ≒ 1.90円 |
約0.5往復 |
※ Nova Micro の「約146往復」は、この1回の出力(161トークン)で割った値です。出力は毎回112〜267トークンとブレるので、実際に1円まで回すと135往復。(136往復目で1円を超えました)
理論値より少し良く見えるのは、入力が1,000トークンに届いていない(581〜888)のと、出力が300で頭打ちになっているからです。
なおClaudeの3モデルはus.プロファイル(米国内のクロスリージョン推論)で計測し、料金表のGlobal単価($3/$15など)で計算しています。us.はGlobal単価の1.1倍で課金されるので、
請求ベースに直すとHaiku 約0.41円、Sonnet 約1.18円(0.85往復)、Opus 約2.09円です。「1円で届かない」という結論は変わりません。ちなみにOpus 4.8だけtemperatureを指定するとエラーになりました(temperature is deprecated for this model)。細かいですが、モデルを差し替えるだけで落ちる例として。
● 1円を使い切るまで投げ続ける
ここがクライマックスです。同じ往復を、累計が1円を超えるまで投げ続けて、何回で止まるかを数えました。
spent = 0
while spent < 1 / 159.4: # 1円ぶんのドル
r = call(model_id, PROMPT_JA)
spent += cost_usd(r["usage"])
n += 1
|
モデル |
1円を超えたのは何往復目か |
累計 |
所要時間 |
|
Nova Micro |
136往復目 |
1.0021円 |
159秒 |
|
Claude Haiku 4.5 |
3往復目 |
1.1295円 |
10秒 |
|
Claude Sonnet 4.6 |
1往復目 |
1.0387円 |
6秒 |
Nova Microは135往復ぶんの要約を吐き出してようやく1円。Sonnetは1回しゃべったら1円を超えました。同じ1円で、135回と0回です。
Nova Microは出力が112〜267トークンとかなりブレる(maxTokensに当たらず自然に終わる)ので、平均185トークンで計算すると理論値の81往復より多く回りました。逆にHaikuは毎回きっちり300で頭打ち。「1円で何回」は、モデルの単価だけでなくそのモデルがどれだけしゃべりたがるかにも左右されます。
③ おまけ検証:日本語は割高なのか
同じ内容のガイドライン文(日本語352字/英語755字・120語)を投げて、inputTokensだけ比べました。
|
モデル |
日本語 tok |
英語 tok |
日/英 |
日本語 文字/tok |
英語 文字/tok |
|
Claude Haiku 4.5 / Sonnet 4.6 |
292 |
167 |
1.75倍 |
1.21 |
4.52 |
|
Nova Micro |
194 |
149 |
1.30倍 |
1.81 |
5.07 |
同じ情報を伝えるのに、Claudeだと日本語は英語の1.75倍のトークンを食います。英語は1トークンで4.5文字進むのに、日本語は1.2文字しか進まない。Novaのトークナイザは日本語に少し強くて1.3倍で済んでいます。
つまり「1円で買えるのはトークンで、トークンで買えるのは情報。その換算レートは言語で違う」。先ほどの「1円でSonnet 0.9往復」は日本語の話で、出力も同じ比率で減るとすれば、英語なら同じ内容で1往復半くらいできる計算です。
■ 使い分けの指針
|
状況 |
支配的なコスト |
先にやること |
|
実行が短く回数が多い(128MBで数十ms以下) |
リクエスト課金($0.2/100万) |
arm64より前に回数を減らす(バッチ化、イベントの間引き) |
|
重くて長い(数秒〜) |
GB-秒 |
CPUバウンドならメモリを上げても料金は同じで速くなる(実測:128MB→1GBで料金同額・8倍速)。I/O待ち中心なら効かないので要実測 |
|
分類・抽出・ルーティング |
モデル単価 |
Nova Micro / Liteで十分。ここにSonnetを置くのが一番高い癖 |
|
品質が要る一発勝負 |
モデル単価 |
Sonnet / Opus。ただし1往復1〜2円の前提で設計する |
|
日本語がメイン |
入力トークン |
同じ内容で英語の1.3〜1.75倍と見込む。長いシステムプロンプトは特に効く |
月額の簡易式はこれで十分です。
月額 ≒ 1往復のコスト × 1日の往復数/人 × ユーザー数 × 稼働日数
例:Sonnet 1.2円 × 20往復 × 100人 × 20日 = 48,000円/月
Nova Micro 0.012円 × 同条件 = 480円/月
■ 後片付け
作るのは一瞬、片付けは意外と気を遣います。
- Lambda関数 one-dollar-lambda・one-dollar-heavy-128・one-dollar-heavy-1024(叩かれる側)と one-dollar-invoker(叩く側)
- CloudWatch Logs のロググループ /aws/lambda/one-dollar-lambda など(残すと取り込み・保存課金が続く。関数を消しても自動では消えません)
- 検証用に流用したIAMロール(今回は既存を流用したので触らず)。関数に付けたリソースポリシーは関数と一緒に消えます
- for fn in one-dollar-lambda one-dollar-heavy-128 one-dollar-heavy-1024 one-dollar-invoker; do
aws lambda delete-function --function-name $fn --region us-east-1
aws logs delete-log-group --log-group-name /aws/lambda/$fn --region us-east-1
done
実際にやってみると、関数を消した後にロググループを消しても、数十秒後に復活していました。直前の1万回ぶんのログがまだ配信中で、届いた瞬間に再作成されるためです。関数削除→少し待つ→ロググループ削除→もう一度確認、の順が安全です。
あと、こういう検証をするときはAWS Budgetsを仕込んでおくと安心です。
■ まとめ
一番の収穫は、「安い」は感想で、「1ドルで何回」は仕様だと分かったことでした。
Lambdaの1ドルもBedrockの1円も、同じ金額の中で100倍〜1万倍の幅があります。
ただしその幅を決めていたのは、Lambdaなら「メモリ設定」ではなく「処理の重さ」、AIなら「モデルの選択」でした。3秒のCPU処理はメモリを8倍にしても料金が同じだった一方で、モデルをSonnetに固定した瞬間、単位あたりの回数はガクッと落ちます。
つまりコストの大半は料金表ではなく、自分の設計が決めているということです。
個人的に面白かったのは、日本語トークンの話でした。1円で買えるのはトークンで、トークンで買えるのは情報。その換算レートが言語で違う(しかもモデルでも違う)というのは、言われてみれば当然なのに意識していませんでした。
※この記事は2026年8月時点の料金・為替(1ドル159.4円)に基づきます。単価は改定されるので、必ず公式の料金ページで最新をご確認ください。