LLM APIのレート制限・スロットリング対策ガイド|429を捌く【2026】
結論: LLM APIのレート制限(429 Too Many Requests)は、Retry-Afterヘッダを尊重した指数バックオフ+ジッターでの再送と、送信側での並列度制御・トークンバケット・キューイングを組み合わせることで、ほぼ確実に捌けます。
この記事の要点:
- 要点1: OpenAIはRPM/TPM、AnthropicはRPM/ITPM/OTPMなど、レート制限は「リクエスト数」と「トークン数」の複数軸で別々に課される。どれか1つでも超えれば429になる
- 要点2: 429時は固定リトライではなく、指数バックオフ+ジッターで再送し、
Retry-Afterヘッダがあればその秒数を最優先で尊重する - 要点3: そもそも429を出さないために、送信側で並列度の上限・トークンバケット・優先度付きキュー・Batch APIを使い、自分でスループットを整流する
対象読者: LLM APIを本番運用していて、利用量の増加とともに429に当たり始めた開発者・SRE
難易度: 中級
読了時間: 約16分
「ローカルでは普通に動いていたのに、本番でユーザーが増えた途端、ログに 429 Too Many Requests が並び始めた」——LLM APIを使うサービスを運用していると、ほぼ全員が一度はこの壁にぶつかります。バックオフを雑に1つ入れてしのいでいるものの、ピーク時は相変わらず詰まる。そんな状態の方は多いのではないでしょうか。
レート制限は「上限に当たったらどう再送するか」という受け側の対応だけでなく、「そもそも上限に当てない」という送り側の制御までセットで設計して初めて安定します。本記事は前者(バックオフ・Retry-After)と後者(並列度制限・トークンバケット・キュー・優先度・Batch API)を、擬似コード付きで一気通貫に解説します。
なお、本番でAPIが「落ちない」ための回復性設計(タイムアウト・冪等性・リトライ全般)については本番で落ちないAIエージェントの作り方|信頼性設計で別途解説しています。本記事はその中でも「LLM APIのレート制限(429)に特化した整流」に絞って深掘りします。
レート制限の仕組み — RPM・TPM・トークン/リクエスト軸とプロバイダ差
まず押さえるべきは、LLM APIのレート制限が単一の数値ではないということです。リクエスト数とトークン数という別々の軸で、それぞれ上限が設定されています。OpenAIの公式ドキュメントは、レート制限が以下のような複数の単位で測られ「いずれかに最初に到達した時点」で制限がかかると説明しています(2026年6月時点・最新は公式で確認)。
- RPM(requests per minute / 1分あたりリクエスト数)
- RPD(requests per day / 1日あたりリクエスト数)
- TPM(tokens per minute / 1分あたりトークン数)
- TPD(tokens per day / 1日あたりトークン数)
- IPM(images per minute / 画像生成モデル向け)
Anthropic(Claude API)も同様にトークン軸を入力と出力で分け、より細かい3軸で管理しています。
| 軸 | 意味 | 当たりやすいワークロード |
|---|---|---|
| RPM | 1分あたりのリクエスト数 | 短いプロンプトを大量に投げる/高並列バッチ処理 |
| ITPM(入力トークン/分) | 送信した入力トークンの合計(Anthropic) | 長文コンテキスト・RAG・大きなシステムプロンプト |
| OTPM(出力トークン/分) | 生成された出力トークンの合計(Anthropic) | 長文生成・コード生成・要約の大量並列 |
| TPM(トークン/分) | 入出力合算のトークン数(OpenAI) | 上記すべて |
ここで重要な落とし穴が2つあります。1つ目は、RPMに余裕があってもTPM/ITPMで詰まるケース。1リクエストあたりのトークンが大きいRAGや長文要約では、リクエスト数は少なくてもトークン軸が先に天井に当たります。2つ目は、プロバイダ・プラン(Tier)・モデルごとに上限が違うこと。具体的な数値はプロバイダやプランで頻繁に変わるため、本記事では断定せず、必ずAnthropic公式・OpenAI公式で最新値を確認してください。
固定ウィンドウではなくトークンバケットで補充される
Anthropicは公式に、固定ウィンドウ(毎分0秒にリセット)ではなくトークンバケットアルゴリズムで制限を管理していると説明しています。バケットの容量が連続的に補充されるため、「分の境界で一気にリセットされる」前提でリクエストをまとめて投げると、補充が追いつかず即429になります。つまり、リクエストは時間的にならして(整流して)流すのが正解です。後述するトークンバケット方式の送信制御は、まさにこのサーバ側の挙動とリズムを合わせる狙いがあります。
429への正しい対応 — 指数バックオフ+ジッターとRetry-Afterの尊重
上限に当たって429が返ってきたときの鉄則は2つです。(1) Retry-Afterヘッダがあれば最優先で従う、(2) なければ指数バックオフ+ジッターで再送する。
HTTPの429 Too Many Requestsは、サーバがRetry-Afterヘッダで「何秒後に再試行すべきか」を示せる、とMDNが定義しています。Anthropicの429レスポンスにもretry-afterヘッダが含まれ、超過した制限の種類(RPM超過かトークン超過か)に応じたリセット時刻に整合した秒数が返されます。このヘッダが返る限り、自前のバックオフ計算より優先すべきです。サーバが「これだけ待て」と明示している以上、それより短く再送すれば再び429を踏むだけだからです。
なぜ「固定スリープ」や「ジッターなし」がダメなのか
429を踏んだ全クライアントが「3秒待って一斉に再送」すると、3秒後にまた全員が同時に殺到し、再び429——というサンダリングハード(thundering herd)が起きます。AWSのBuilders’ Library「Timeouts, retries, and backoff with jitter」は、待ち時間を指数的に増やすだけでなくジッター(ランダムなゆらぎ)を加えて再送タイミングを散らすことが、競合を減らしシステム全体を速く回復させると解説しています。OpenAIの公式ガイドも、リトライ実装例としてwait_random_exponential(ジッター込みの指数バックオフ)を提示しています。
実装イメージ(擬似コード)
429・5xxに対して、Retry-After優先 → なければ指数バックオフ+フルジッター、という再送ループの擬似コードです。
FUNCTION call_with_retry(request):
base = 1.0 # 初期待機(秒)
cap = 60.0 # 待機の上限(秒)
max_attempts = 6
FOR attempt IN 0 .. max_attempts-1:
response = send(request)
IF response.status == 200:
RETURN response
IF response.status == 429 OR response.status >= 500:
# (1) Retry-After があれば最優先で尊重する
IF response.has_header("Retry-After"):
wait = parse_seconds(response.header("Retry-After"))
ELSE:
# (2) 指数バックオフ + フルジッター
# exp = base * 2^attempt を cap で頭打ちにし、
# 0〜exp の一様乱数で再送時刻を散らす
exp = min(cap, base * (2 ** attempt))
wait = random_uniform(0, exp)
sleep(wait)
CONTINUE # 次の試行へ
ELSE:
# 4xx(429除く)など、リトライしても直らないエラーは即時に投げる
RAISE NonRetryableError(response)
RAISE RateLimitExceeded("max retries reached")
ポイントは3つです。第一に、リトライ対象は429と5xxに限定し、400系のバリデーションエラーなどは即座に失敗させること(無駄な再送はTPMを食うだけです)。第二に、待機の上限(cap)を設けて待ち時間が無限に伸びないようにすること。第三に、最大試行回数を決め、超えたら明示的に上位へエラーを返すことです。多くの公式SDK(OpenAI・Anthropic)はこのリトライをデフォルトで内蔵しているため、まずはSDKの自動リトライ設定(最大回数など)を活用し、独自実装は必要な箇所に絞るのが現実的です。
送信側の制御 — 並列度の制限・トークンバケット・キューイング
バックオフは「当たった後」の対処です。安定運用の本丸は、そもそも上限に当てない送信側の整流にあります。ここを実装せずバックオフだけに頼ると、ピーク時にリトライが膨らみ、レイテンシが悪化し続けます。
① 並列度(concurrency)の上限を固定する
最も効くのが並列度の上限です。「同時に飛んでいるリクエストはN本まで」とセマフォで縛り、Nを超える分は待たせます。これだけでRPMの暴発がかなり収まります。
semaphore = Semaphore(max_concurrency = 8) # 同時実行は8本まで
FUNCTION worker(request):
semaphore.acquire()
TRY:
RETURN call_with_retry(request) # 前章のリトライ付き送信
FINALLY:
semaphore.release()
適切なNは、自分のTier上限と1リクエストあたりの平均トークン・平均レイテンシから逆算します。「RPM上限 ÷ 60秒 × 平均レイテンシ秒」がおおよその安全な同時実行数の目安です。トークン軸も考慮するため、長文を扱うほどNは小さくする必要があります。
② トークンバケットで「速度」を整流する
並列度の上限が「同時本数」の制御なのに対し、トークンバケットは「毎秒どれだけ流すか」というレート(速度)の制御です。Anthropicがサーバ側で採用しているのと同じ考え方をクライアント側にも置くことで、リズムを合わせられます。ここでの「トークン」はバケットの許可証であり、LLMのトークンとは別概念ですが、1リクエストの消費を見込みトークン数に応じて重み付けすれば、TPM軸の整流にも使えます。
CLASS TokenBucket(rate_per_sec, capacity):
tokens = capacity
last = now()
FUNCTION acquire(cost = 1):
# 経過時間に応じて連続的に補充(固定ウィンドウではない)
elapsed = now() - last
tokens = min(capacity, tokens + elapsed * rate_per_sec)
last = now()
IF tokens >= cost:
tokens = tokens - cost
RETURN true # 送信OK
ELSE:
wait = (cost - tokens) / rate_per_sec
sleep(wait) # 補充されるまで待つ
tokens = 0
RETURN true
# TPM軸の整流に使う場合:cost に見込み入力トークン数を渡す
bucket = TokenBucket(rate_per_sec = TPM_LIMIT / 60, capacity = TPM_LIMIT / 60 * 2)
bucket.acquire(cost = estimate_input_tokens(request))
③ キューイングでバーストを吸収する
並列度とトークンバケットを「出口」とすれば、キューはその手前の緩衝材(バッファ)です。突発的なバーストをいったんキューに溜め、ワーカーが整流された速度で取り出して送信します。これにより、上流のスパイクを下流のAPIに直接ぶつけずに済みます。リトライ待ちのリクエストもキューに戻す設計にすると、全体が1つの整流された流れにまとまります。
バッチ・優先度設計 — 重要度で捌き、Batch APIを使い分ける
すべてのリクエストが「今すぐ返ってほしい」わけではありません。緊急度でレーンを分けると、限られたレート上限を有効に使えます。
優先度付きキューで重要なリクエストを守る
ユーザーが画面の前で待っているインタラクティブな呼び出し(高優先度)と、夜間バッチや非同期の要約処理(低優先度)を同じキューに突っ込むと、後者が前者のレート枠を食い潰します。優先度キューで高優先度を先に出し、低優先度はレート枠が空いているときだけ流す設計にします。
| 優先度 | 例 | 扱い |
|---|---|---|
| 高(同期) | チャット応答・ユーザー操作起点 | 枠を最優先で割り当て・低レイテンシ重視 |
| 中(準リアルタイム) | 通知文生成・補助提案 | 高優先度が空いた枠で処理 |
| 低(非同期) | 夜間の一括要約・ログ分類・埋め込み生成 | Batch APIへオフロード/空き枠で消化 |
Batch APIで通常レート枠から逃がす
「24時間以内に返ればよい」大量処理は、リアルタイムのレート枠を消費させずにBatch APIへ逃がすのが定石です。OpenAIのBatch APIは、24時間の完了ウィンドウを受け入れる代わりに、通常モデルが50%割引になり、しかも通常のレート制限とは別枠(separate pool)で処理されます(2026年6月時点・最新は公式で確認)。つまり夜間の一括処理をBatchに移すだけで、(1) コストが半減し、(2) 日中のインタラクティブ用レート枠が空く、という二重の効果が得られます。低優先度ワークロードをBatchへ寄せることは、レート制限対策として最も費用対効果が高い一手です。
なお、トークン削減そのものでレート圧を下げたい場合は、繰り返しの問い合わせに対するセマンティックキャッシュの併用も有効です。キャッシュヒットした分はそもそもAPIを叩かないため、TPM/RPMの両方を直接的に節約できます。
監視と上限引き上げ — 観測すべき指標と申請の考え方
整流の仕組みを入れたら、最後は「いま上限のどこまで使っているか」を可視化します。観測なしにNやrateをチューニングするのは当て推量です。
観測すべき指標
- 429発生率:全リクエストに対する429の割合。1%を超え始めたら整流設計を見直すサイン
- レート枠の使用率:プロバイダが返すレート残量ヘッダ(例:Anthropicの
anthropic-ratelimit-tokens-reset等)をログに出し、RPM/TPMそれぞれの消費率を追う - リトライ回数の分布:1リクエストあたり何回リトライしているか。平均が増えていれば上限に近づいている
- キュー滞留時間:キューに入ってから送信されるまでの待ち時間。これが伸びるとユーザー体感レイテンシが悪化する
エージェント全体のメトリクスやトレースを統合的に観測する方法はAIエージェント実装ロードマップでも触れています。レート関連指標はこうした既存の可観測性基盤に乗せると運用が一本化できます。
上限引き上げ(Tier graduation)の考え方
整流とキャッシュを尽くしても恒常的に枠が足りないなら、上限引き上げを検討します。OpenAIは公式に、API利用額(spend)が増えると自動的に次のUsage Tierへ昇格し、ほとんどのモデルでレート上限が上がると説明しています。Anthropicも同様にTier制を採り、Tier 4を超えるカスタム上限はセールスへの相談が必要です。重要なのは順序で、(1) 並列度・トークンバケットで整流 → (2) Batch・キャッシュで枠を節約 → (3) それでも足りなければ上限引き上げ、という順に進めることです。整流せずに上限だけ上げると、同じ非効率を高いコストで繰り返すことになります。
【注意】レート制限対策でやりがちな失敗パターン
実装時にハマりやすい4つの落とし穴を、❌/⭕形式でまとめます。
失敗1:Retry-Afterを無視して自前のバックオフだけで再送する
❌ サーバが「30秒待て」と返しているのに5秒で再送し、再び429を踏む
⭕ Retry-Afterがあればその秒数を最優先。自前のバックオフはヘッダがないときのフォールバックにする
失敗2:ジッターなしの固定間隔リトライ
❌ 全クライアントが同じ秒数で一斉に再送し、サンダリングハードで回復が遅れる
⭕ 指数バックオフにランダムなジッターを必ず加え、再送タイミングを散らす
失敗3:RPMだけ見てTPM/ITPMを見ていない
❌ リクエスト数に余裕があるのに、長文コンテキストでトークン軸が先に天井に当たり原因不明の429に悩む
⭕ リクエスト軸とトークン軸を別々に監視・整流する。長文ワークロードはトークン軸を主に考える
失敗4:4xxエラーまでリトライしてしまう
❌ 400(不正リクエスト)や401(認証エラー)まで再送し、無駄にTPMを消費しながら永遠に直らない
⭕ リトライ対象は429と5xxに限定。それ以外の4xxは即座に失敗させる
まとめ: 今日から始める3つのアクション
- 今日: 自分のコードのリトライ実装を確認し、429に対して「Retry-After優先 → なければ指数バックオフ+ジッター」になっているかをチェックする(多くの公式SDKは内蔵済みなので、まずは設定を確認)
- 今週中: 送信側にセマフォで並列度の上限を1つ入れる。あわせて429発生率とリトライ回数をログに出し、現状の消費率を可視化する
- 今月中: 「24時間以内でよい」大量処理をBatch APIへ逃がし、繰り返し問い合わせにはセマンティックキャッシュを併用。整流とコスト削減を尽くしたうえで、なお足りなければTier引き上げを検討する
AIエージェント・ツールの最新情報をキャッチアップしたい方へ
Agent Labでは、週1回のニュースレターでAIツールの最新比較・活用事例をお届けしています。
あわせて読みたい:
- 本番で落ちないAIエージェントの作り方|信頼性設計 — タイムアウト・冪等性・リトライ全般の回復性設計
- セマンティックキャッシュ実践ガイド — APIを叩かずにTPM/RPMを節約する
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』(SBクリエイティブ)。
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。

参考・出典
- Rate limits — OpenAI(参照日: 2026-06-06)
- Batch API — OpenAI(参照日: 2026-06-06)
- Rate limits — Anthropic(参照日: 2026-06-06)
- Our approach to rate limits for the Claude API — Anthropic(参照日: 2026-06-06)
- Timeouts, retries, and backoff with jitter — Amazon Builders’ Library(参照日: 2026-06-06)
- 429 Too Many Requests — MDN Web Docs(参照日: 2026-06-06)
- Retry-After header — MDN Web Docs(参照日: 2026-06-06)
