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-remaining が 0 の場合は x-ratelimit-reset (UTC エポック秒)、それ以外の場合は少なくとも 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