API は、アプリが一定期間内に API が許可するリクエスト数を超えて要求を送信したときに、429 Too Many Requests を返します。 要求自体は問題ありません。 送信頻度が高すぎるため、API によって拒否されました。 待機してもう一度送信すると、通常は成功します。 応答には、多くの場合、待機する時間を示す Retry-After ヘッダーが含まれています。 詳細については、 RFC 6585、セクション 4 を参照してください。
人気のある API での 429 レスポンス
各 API では、レート制限が異なる方法で実装されます。 状態コード、ヘッダー、およびエラー本文はすべて異なるため、1 つの API を正しく処理するコードが次の API を誤って処理する可能性があります。
| API | Status | どれくらい待てばよいかを判断する方法 | 〇〇に気を付けて |
|---|---|---|---|
| GitHub |
403 または 429 |
retry-after 存在する場合は x-ratelimit-reset (UTC エポック秒)、x-ratelimit-remaining が 0 の場合は、それ以外の場合は少なくとも1分 |
403には、レート制限やアクセス許可の不足が考えられます。 ヘッダーを読んで見分けてください。 |
| OpenAI | 429 |
retry-after |
credit_balance_exhausted で示されるもののように、一部の 429 は再試行しても役に立ちません。
error.codeを確認します。 |
| Anthropic | 429 |
retry-after |
支出上限 429 には retry-after が設定されておらず、アクセスが再開されるまで失敗し続けます。 過負荷状態の API は、429ではなく、529を返します。 |
| Microsoft Graph | 429 |
Retry-After (秒) |
制限は、SharePointやOutlookなど、サービスごとに異なります。 |
429 を処理する方法
- 再試行するかどうかを決定します。 クォータ、クレジット、または利用上限が使い切れているというエラーが表示された場合、再試行しても役に立ちません。 ユーザーに通知し、自分自身に警告します。
- API が要求する限り待ちます。 応答に
Retry-Afterが含まれている場合は、その時間だけ待機します。 秒数または HTTP 日付のいずれかです。 GITHUBのx-ratelimit-resetのように、API がレート制限ヘッダーを代わりに使用する場合は、リセット時刻まで待ちます。 - それ以外の場合は、手を引いてください。 API からのヒントなしで、指数バックオフとランダム ジッターを使用して再試行し、数回試行した後に停止します。
- ユーザーに何が起こっているのかを伝えます。 「ビジー、5 秒で再試行」は、決して終了しないスピナーより良いです。
- 次の429の前で速度を落としてください。 API がレート制限ヘッダーを送信する場合は、残りのカウントを使用して要求のペースを設定します。
async function fetchWithRetry(url, options, attempts = 3) {
for (let attempt = 1; ; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429 || attempt === attempts) {
return response;
}
const retryAfter = response.headers.get('retry-after');
const waitMs = retryAfter
? (isNaN(retryAfter) ? new Date(retryAfter) - Date.now() : retryAfter * 1000)
: 2 ** attempt * 1000 + Math.random() * 1000;
await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 0)));
}
}
多くのSDKは、429を自動的に再試行します。 たとえば、OpenAI Python SDK は既定で 2 回再試行し、.NET標準の回復性ハンドラーは 3 回再試行し、Retry-Afterを尊重します。 SDK の再試行回数を使い切ると、コードがそのエラーを受け取るため、プランが必要です。
アプリが 429 を処理することをテストする方法
開発中に 429 が表示されることはほとんどありません。 API は高速で、自分だけがユーザーであり、テスト データは小さいです。 そのため、429 の処理をテストする方法によって、ユーザーが見つける前にバグが見つかるかどうかが決まります。
| Approach | 見つけたもの | 見逃している内容 |
|---|---|---|
| 本番を待機する | 実際の失敗 | すべて、ユーザーがそれをクリックするまで |
| テストで API をモックするか、コーディング エージェントにモックを記述させる | 再試行ブランチを実行するかどうか | API の実際の状態コード、ヘッダー、エラー本文、および SDK の再試行ポリシー。 アプリでは、モックに到達するためにテスト専用のスイッチも必要です。 |
| レート制限されるまで実際の API を呼び出す | 実動作 | 429 をオンデマンドでトリガーすることはできません。実際のクォータを使い切ってしまいます |
| アプリの実際のトラフィックをインターセプトし、オンデマンドで 429 を返す | 実際の URL、実際の SDK と再試行ポリシー、API 独自の 429 形式 | アプリ内では何も変更されないため、コードを分離した状態ではテストしません。 そのためには単体テストを使ってください。 |
自分のアプリで試す
Dev Proxy は、選択した API に対するアプリの要求をインターセプトし、API 独自のヘッダーとエラー形式で 429 を返しますが、アプリは実際の URL を呼び出し続けます。 また、Retry-After の時間になる前にアプリが再試行するタイミングも通知されます。
アプリが呼び出す API のプリセットをダウンロードし、それを使用して Dev Proxy を開始します。
devproxy config get github-rate-limiting
devproxy --config-file "~dataFolder/configs/github-rate-limiting/.devproxy/devproxyrc.json"
| API | Preset |
|---|---|
| GitHub | github-rate-limiting |
| OpenAI | openai-throttling |
| Anthropic | anthropic-throttling |
Microsoft Graph (OneDriveとSharePoint: /drive、/shares、/sites) |
microsoft-graph-rate-limiting |
その後、通常どおりにアプリを実行し、どのように動作するかを確認します。 Dev Proxy をインストールするには、「Dev Proxy を設定する」を参照してください。
次のステップ
参照
Dev Proxy