GPT APIを呼び出す関数をリリースしました。ステージングでは問題なく動作していました。しかし、本番環境で最初の数百人のユーザーがアクセスした途端、ログは 429 Too Many Requests で埋め尽くされました。これは1分あたりのリクエスト数なのか、1分あたりのトークン数なのか、それとも日ごとの上限なのか。まだティア1のままなのか。先週切り替えたモデルは、古いモデルよりも厳しい制限だったのか。まずはその切り分けが必要です。
💡 この記事では、現在のGPTモデルで確認すべきレート制限の種類と、APIレスポンスヘッダーおよびApidogでの小規模な負荷テストを使って、実際の制限値を確認する手順を紹介します。レート制限の問題を疑ったときに再実行できるワークフローと、チームで共有できるリクエストコレクションを作成できます。
OpenAIのレート制限は、モデルやエンドポイントによって異なります。GPT-5.5はGPT-4.1とは異なる制限を持つ可能性があり、画像モデルはテキストモデルとは別の単位でカウントされます。また、利用ティアは支出や支払い状況に応じて変わります。
Apidogを使うと、以下を1つのワークスペースで確認できます。
- 各リクエストのレスポンスヘッダー
- RPM / TPM の残量
- 同時リクエスト時の429発生タイミング
- チームで再利用できるテストシナリオ
実際に重要な4つの制限
OpenAIは、GPT APIキーに複数のレート制限を適用しています。本番環境で特に確認すべきなのは次の4つです。
- RPM(requests per minute): 1分あたりに送信できるAPIリクエスト数。
- TPM(tokens per minute): 1分あたりに処理できる入力トークンと出力トークンの合計。
- RPD(requests per day): 1日あたりのリクエスト数。無料枠やティア1で影響しやすい制限。
- IPM / TPD / バッチキュー制限: 画像生成、音声、埋め込み、Batch APIなど、エンドポイント固有の制限。
リクエストが拒否されると、APIはHTTP 429と次のようなJSONを返します。
{
"error": {
"message": "Rate limit reached for gpt-5.5 in organization org-abc on tokens per min (TPM): Limit 30000, Used 28432, Requested 3120.",
"type": "tokens",
"param": null,
"code": "rate_limit_exceeded"
}
}
重要なのは、message と type です。
-
tokensならTPM超過 -
requestsならRPM超過 -
tokens_usage_basedなら使用量ベースの制限
同じ429でも、原因によって対処方法は変わります。TPM超過ならプロンプトや max_tokens を見直します。RPM超過ならキューや並行処理制御を入れます。
HTTP 429の一般的な意味は、MDNの429ドキュメント と RFC 6585仕様 を参照してください。OpenAI固有の挙動は、公式のレート制限ページ を確認してください。
ティアの仕組みと、なぜ昇格または停滞するのか
GPT APIキーはOpenAIの利用ティアに属します。ティアによって、RPMとTPMの上限が変わります。
ティアは主に次の2つで決まります。
- アカウントの総支出
- 初回支払いからの経過日数
テキストモデルのおおよその形は次の通りです。
| ティア | 支払い条件 | 待機期間 | テキスト RPM | テキスト TPM |
|---|---|---|---|---|
| 無料 | なし | なし | 3 | 40k |
| 1 | $5支払い済み | なし | 500 | 30k–200k(モデルによる) |
| 2 | $50支払い済み | 7日 | 5,000 | 450k |
| 3 | $100支払い済み | 7日 | 5,000 | 1M |
| 4 | $250支払い済み | 14日 | 10,000 | 2M |
| 5 | $1,000支払い済み | 30日 | 10,000 | 2M+ |
上記は目安です。正確な値は時間とともに変わり、モデルによっても異なります。実装前には、ダッシュボードまたはAPIレスポンスヘッダーからライブの制限値を確認してください。
実務上の注意点は2つです。
支払い後に自動昇格する
ティアは明示的に切り替えるものではありません。支出条件と待機期間を満たすと、次のリクエストから新しい上限が適用されます。降格することもある
長期間非アクティブだったり、支払い方法に問題があったりすると、ティアが下がる可能性があります。請求設定を変更した後は、本番と同じ条件で再テストしてください。
他のモデルプロバイダーとの比較は、OpenAI APIユーザーレート制限解説、Claude APIレート制限ガイド、Grok-3 APIレート制限ガイド を参照してください。
レスポンスヘッダーからライブ制限を読み取る
現在の制限値は、レスポンスヘッダーで確認できます。特に見るべきヘッダーは次の4つです。
-
x-ratelimit-limit-requests: このエンドポイントのRPM上限 -
x-ratelimit-remaining-requests: 現在の1分間に残っているリクエスト数 -
x-ratelimit-limit-tokens: TPM上限 -
x-ratelimit-remaining-tokens: 現在の1分間に残っているトークン数
通常は以下も返ります。
x-ratelimit-reset-requestsx-ratelimit-reset-tokens
これらは、バケットが補充されるまでの時間を示します。例: 6s、1m30s
ステップ1: ApidogでGPTリクエストを設定する
Apidogで新しいプロジェクトを作成し、GPT APIへのリクエストを追加します。
POST https://api.openai.com/v1/chat/completions
Headersには次を設定します。
| キー | 値 |
|---|---|
Authorization |
Bearer {{OPENAI_API_KEY}} |
Content-Type |
application/json |
{{OPENAI_API_KEY}} はApidogの環境変数です。APIキーをリクエスト内に直接書かずに、環境ごとに切り替えられます。個人キー、チームキー、組織ID、プロジェクトIDも同じ方式で管理できます。
Bodyには次を設定します。
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "ping"
}
],
"max_tokens": 10
}
送信後、レスポンスパネルのHeadersタブを開き、x-ratelimit-* を確認します。
この時点で記録すべき値は次の4つです。
x-ratelimit-limit-requests
x-ratelimit-remaining-requests
x-ratelimit-limit-tokens
x-ratelimit-remaining-tokens
これが以降のテストのベースラインになります。
チャット補完リクエストの設定については、ApidogでChatGPT APIをテストする方法ガイド も参考になります。
ステップ2: 意図的なバーストで制限を確認する
ヘッダーを読むだけでは、上限に達したときの挙動は確認できません。実際に小さなバーストを発生させて、429がどの条件で返るかを確認します。
Apidogのテストランナーで、保存したリクエストを複数回実行します。
設定例:
- Iterations:
50 - Concurrency:
10 - Delay between iterations:
0 ms
想定される結果は2つです。
途中で429が返る
ヘッダーに表示された制限値と実際のアカウント状態が一致していると判断できます。50回すべて成功する
想定よりRPMに余裕があります。レスポンスヘッダーのremaining-requestsを確認してください。
429が出たら、そのレスポンスボディを必ず確認します。message に、RPM、TPM、日次上限のどれに抵触したかが書かれています。
429全般の考え方は、レート制限超過ガイド でも解説しています。
ステップ3: RPM超過とTPM超過を区別する
ステップ2のような小さいリクエストは、主にRPMの確認に向いています。TPMを確認するには、リクエスト数を減らし、1リクエストあたりのトークン数を増やします。
Bodyを次のように変更します。
{
"model": "gpt-5.5",
"messages": [
{
"role": "system",
"content": "<ここに3,000トークン分のコンテキスト>"
},
{
"role": "user",
"content": "上記を1つの文に要約してください。"
}
],
"max_tokens": 200
}
次のようなシナリオで実行します。
- Iterations:
20 - Concurrency:
5 - Delay:
0 ms
ティア1でTPM上限が30k程度の場合、リクエスト数の上限に達する前にトークン制限に当たる可能性があります。
切り分け後の対処は次の通りです。
| 原因 | 対処 |
|---|---|
| RPM超過 | キューイング、バッチ処理、ワーカープール、並行数制御 |
| TPM超過 | プロンプト削減、コンテキスト分割、キャッシュ、max_tokens の見直し |
ステップ4: 同時接続ユーザーをシミュレートする
本番トラフィックは単純なバーストではありません。複数ユーザー、異なるリクエストサイズ、継続的なベースライン、突発的なスパイクが混在します。
Apidogでは、以下のようなテストシナリオを作成できます。
- 小さいリクエスト
- 中くらいのリクエスト
- 大きいリクエスト
- ランダムな待機時間
- 複数の同時実行
JavaScriptの事前・事後リクエストスクリプトを使うと、次のような検証もできます。
- 繰り返しごとにメッセージ長をランダム化する
- 各レスポンス後に
x-ratelimit-remaining-tokensを読み取る - 残トークンがしきい値を下回ったらシナリオを停止する
- 200応答と429応答のレイテンシを別々に記録する
テスト後は、ステータスコードのヒストグラムを確認します。これはチームのランブックに貼っておくと便利です。
「今レート制限に当たっているのか?」と聞かれたら、同じシナリオを再実行して比較できます。
スロットリングされた場合の対処法
制限に当たる条件が分かったら、主な選択肢は3つです。
1. バックオフする
GPT呼び出しを指数バックオフ付きの再試行でラップします。
429レスポンスに x-ratelimit-reset-tokens が含まれている場合は、その値を最初の待機時間として使います。
疑似コード:
import time
def call_with_retry(fn, max_retries=5):
for attempt in range(max_retries):
response = fn()
if response.status_code != 429:
return response
reset = response.headers.get("x-ratelimit-reset-tokens")
if reset:
delay = parse_reset_header(reset)
else:
delay = 2 ** attempt
time.sleep(delay)
return response
単純な time.sleep(2 ** attempt) でも動きますが、OpenAIが返すリセット時間を使った方が無駄な待機を減らせます。
2. キューに入れる
バーストトラフィックが原因なら、リクエストをキューに入れて、制限値を少し下回る速度で処理します。
典型的には、TPMまたはRPMに合わせたトークンバケットリミッターを使います。
実装の考え方は、APIレート制限の実装方法 と APIでのレート制限の実装 を参照してください。
3. Batch APIに逃がす
同期で処理する必要がないワークロードは、Batch APIに移行できます。
向いている処理の例:
- 夜間のデータエンリッチメント
- ドキュメント分類
- 埋め込みの再構築
- 24時間以内に完了すればよい非同期処理
同期クォータをユーザー向けトラフィックに残せるため、本番の429を減らしやすくなります。
スロットリングとレート制限の違いは、スロットル vs. レート制限 が参考になります。
一般的なGPT 429エラーと意味
よく見る429は、ほぼ次の3つです。
Rate limit reached … on requests per min (RPM)
1分あたりのリクエスト数が多すぎます。
対処:
- 並行数を下げる
- ワーカープールを使う
- レコードを全件同時に
mapしない - RPMを安全係数で割った値を上限にする
例:
安全な並行数 = RPM / 2
Rate limit reached … on tokens per min (TPM)
1分あたりのトークン消費が多すぎます。
対処:
- システムプロンプトを削る
- RAGで渡すドキュメント量を減らす
- コンテキストを分割する
-
max_tokensを現実的な値に下げる - キャッシュできるコンテキストはキャッシュする
You exceeded your current quota, please check your plan and billing details
429に見えますが、実際には請求・クォータの問題です。
考えられる原因:
- 月間支出上限に達した
- 登録カードが無効
- 前払い残高がゼロ
- 請求設定に問題がある
この場合、コードではなく請求ダッシュボードで修正します。
よくある質問
ApidogでGPTのレート制限をテストするのに費用はかかりますか?
いいえ。無料プランで単一リクエストのテストや小規模な同時実行テストができます。
より大きなテスト負荷、チームワークスペース、スケジュール実行が必要な場合は有料プランを検討してください。詳細は Apidogの料金 を確認してください。
実際のトークンを消費せずにレート制限をテストできますか?
部分的には可能です。
最小コストの確認方法は、次のようなリクエストです。
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "p"
}
],
"max_tokens": 1
}
レスポンスヘッダーは返るため、制限値の確認には使えます。
ただし、バーストテストでは実際のトークンを消費します。完全にオフラインで再試行ロジックだけ検証したい場合は、Apidogのモックサーバーで429レスポンスを再現できます。
ティア1のキーが同僚のティア1のキーより遅く感じるのはなぜですか?
ティアの上限はキー単位ではなく、組織単位です。
同じ組織内で他のユーザーが大量にAPIを使っている場合、同じRPM / TPMを共有しています。
確認方法:
- 自分のキーで同じリクエストを実行
- 同僚のキーで同じリクエストを実行
-
x-ratelimit-remaining-tokensの減り方を比較
どのモデルにどの制限があるか、どう確認すればよいですか?
レスポンスヘッダーを確認してください。
記事内の表は目安です。実際の制限値は、モデル、ティア、時期によって変わります。
Apidogから各モデルに安価なリクエストを1つ送信し、次を記録します。
x-ratelimit-limit-requests
x-ratelimit-limit-tokens
同じ系列でも、gpt-5.5 と gpt-5.5-0901 のようにスナップショットが違うと制限が異なる場合があります。
ストリーミングリクエストは異なるカウント方法になりますか?
TPMについては注意が必要です。
ストリーミングリクエストでは、max_tokens に基づいてトークンが事前に予約される場合があります。実際の出力が短くても、max_tokens が大きいとTPM予算を圧迫します。
対処:
{
"max_tokens": 200
}
必要以上に大きな値を設定せず、現実的な上限にしてください。
ストリーミングのテスト方法は、ApidogでChatGPT APIをテストする方法 でも解説しています。
Apidogのレート制限テストをチームと共有できますか?
はい。共有プロジェクトにリクエストとテストシナリオを保存できます。
チームメンバーは自分の環境変数にAPIキーを設定し、同じシナリオを実行できます。
これにより、次のような切り分けがすぐにできます。
- 自分のキーだけがスロットリングされているのか
- 組織全体の制限に当たっているのか
- モデル変更後に上限が変わったのか
- プロンプト変更でTPMを使い切っているのか
Top comments (0)