429 Too Many Requests: その意味と対処方法

API は、アプリが一定期間内に API が許可するリクエスト数を超えて要求を送信したときに、429 Too Many Requests を返します。 要求自体は問題ありません。 送信頻度が高すぎるため、API によって拒否されました。 待機してもう一度送信すると、通常は成功します。 応答には、多くの場合、待機する時間を示す Retry-After ヘッダーが含まれています。 詳細については、 RFC 6585、セクション 4 を参照してください。

各 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 を処理する方法

  1. 再試行するかどうかを決定します。 クォータ、クレジット、または利用上限が使い切れているというエラーが表示された場合、再試行しても役に立ちません。 ユーザーに通知し、自分自身に警告します。
  2. API が要求する限り待ちます。 応答に Retry-After が含まれている場合は、その時間だけ待機します。 秒数または HTTP 日付のいずれかです。 GITHUBのx-ratelimit-resetのように、API がレート制限ヘッダーを代わりに使用する場合は、リセット時刻まで待ちます。
  3. それ以外の場合は、手を引いてください。 API からのヒントなしで、指数バックオフとランダム ジッターを使用して再試行し、数回試行した後に停止します。
  4. ユーザーに何が起こっているのかを伝えます。 「ビジー、5 秒で再試行」は、決して終了しないスピナーより良いです。
  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 を設定する」を参照してください。

次のステップ

参照