ウェブと開発 / CLEARBYTE

HTTP 429 Too Many Requests:Retry-After と安全な再試行の設計

HTTP 429 はサーバーによるレート制限を示します。応答と Retry-After を確認し、共有する要求レートを下げたうえで、繰り返しても安全な操作だけを再試行します。総期限と試行回数の上限が必要です。

このガイドの内容

手動では正常に動く連携でも、バッチ処理を始めると失敗することがあります。個々のワーカーの要求は少なく見えても、合計するとアカウント全体の制限を超えるためです。429 を受けた全ワーカーがすぐ同じ要求を送るのではなく、処理全体の負荷へのフィードバックとして扱います。

ここでは調査記録、キューの予算、待機時間の計算例を示します。数値は制限が公開された架空サービスの例であり、特定 API の実際の上限ではありません。エラーを返したサービスの契約と資料を必ず確認してください。

最初に 429 を返したコンポーネントを特定する

要求時刻、エンドポイント、メソッド、ステータス、要求 ID、再試行に関する応答ヘッダーを記録します。認証ヘッダーや個人データはログに残しません。対象 API、リバースプロキシ、CDN のルールのどこから返された応答かを確認します。ブランド付きのエラーページだけでは制限方式を特定できません。

MDN が説明するように、制限は IP、認証済みユーザー、アプリ、リソースなどに適用されます。応答本文や管理画面で対象の割り当てを確認します。分当たりの要求数、同時実行数、日次総量では対策が異なります。日次枠の使い切りは、キューを遅くするだけでは回復しません。

  • ジョブが増えたのか、あるジョブの再試行が増えたのかを確認する。
  • サービス、タブ、API キーが同じアカウント枠を共有していないか調べる。
  • 制限対象が要求数、実行中要求、トークン、その他の資源のどれかを確認する。
  • 公開された回復時刻がユーザー操作の期限に間に合うか確認する。

Retry-After の単位を正しく読む

Retry-After は非負整数の秒数、または HTTP 日付です。値が 12 なら、受信後の待機は十二秒であり、十二ミリ秒ではありません。日付の場合は信頼できる時計で残り時間を計算します。過去の日付だからといって無制限の即時再試行をしてはいけません。

待機可能なキューでは、有効なサーバー指定時間を最低待機時間にします。多数のワーカーが再開する場合は、さらに小さなランダムなずれを加えます。指定時間がジョブの残り期限を超えるなら停止または再予約します。独自の最大値で待機を切り縮め、早すぎる要求を続けないようにします。

429 応答を受けた場合の判断例
観測した応答解釈このジョブでの対応
Retry-After: 12待機時間は 12 秒期限が許せば最低 12 秒待つ
Retry-After: HTTP 日付受信時刻と時計精度で間隔が決まる非負の間隔を計算して期限を確認
ヘッダーなし、または無効利用できる指定時間がないサービスの規則か上限付きバックオフを使う
日次割り当てを使い切ったとの説明短時間の再試行では枠が戻らない枠が利用可能になるまで停止

ワーカー単位ではなく共有キュー全体を予算化する

アカウント全体で毎分 120 要求が許可され、処理に 600 要求が必要だとします。他の利用がなくても、件数だけで最低五分の枠が必要です。十秒で全部送って五十秒休む方式はバーストです。分平均が合っていても拒否される可能性があります。

この例では他の処理の余地を残して毎分 90 要求を運用目標にします。毎秒 1.5 要求なので、開始間隔は約 667 ミリ秒です。600 要求には約 400 秒かかり、応答時間と再試行は別に考えます。これは計画上の算術であり、すべてのサービスの時間窓に合うという保証ではありません。

平均応答時間が 2 秒なら、安定した負荷におけるリトルの法則による平均処理中件数は 1.5 × 2 = 3 です。セマフォは同時実行を、共有レート制限は開始間隔を制御します。片方だけでは両方を制御できません。再試行も初回要求と同じ予算に含めます。

Example workload assumptions:
Account allowance: 120 requests/minute
Operating target: 90 requests/minute = 1.5 requests/second
600 requests / 1.5 requests/second = 400 seconds
Average concurrency at 2 seconds/response: 1.5 × 2 = 3

指定時間がない場合は上限付きバックオフとジッターを使う

失敗が続くにつれて待機ウィンドウを広げ、その範囲内で実際の待機時間をランダムに選ぶ方法があります。例えば一、二、四、八秒の窓と別の総期限を用意します。ジッターで再開をずらし、全ワーカーが同時刻に再び集中する状態を防ぎます。

次の関数は待機時間を計算するだけで、要求送信や完全な再試行クライアントではありません。呼び出し側で期限、回数上限、キャンセル、操作の安全性を管理します。ブラウザーから Retry-After を読むには、サーバー側でそのヘッダーを CORS により公開する必要がある場合もあります。

function retryDelayMs(retryAfter, attempt, nowMs = Date.now()) {
  const text = String(retryAfter ?? "").trim();
  if (/^\d+$/.test(text)) {
    const milliseconds = Number(text) * 1000;
    return Number.isSafeInteger(milliseconds) ? milliseconds : Infinity;
  }
  if (/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(text)) {
    const dateMs = Date.parse(text);
    if (Number.isFinite(dateMs)) return Math.max(0, dateMs - nowMs);
  }
  const windowMs = Math.min(8000, 1000 * 2 ** attempt);
  return Math.floor(Math.random() * windowMs);
}
// Example policy: at most 4 retries and a 30-second total deadline.
// If the required wait exceeds the remaining deadline, stop.

同じ操作を繰り返して安全か確認する

リソースの読み取りと支払いの作成は異なります。書き込みの再試行前に、サービスの冪等性の契約と、前の操作が既に反映された可能性を確認します。対応している場合は、同じ論理操作に同じ冪等キーを再利用します。試行ごとに新しいキーを作ると、別の操作を複数作ることがあります。

SDK が内部で再試行することもあります。その外側にさらにループを付けると通信回数が増幅します。すべての層を合わせた最大ネットワーク試行回数を明文化します。ユーザー操作では、長時間回り続けるボタンの裏にキューを隠すのではなく、後で試せる分かりやすい状態を表示します。

  • 総期限を一つ設定し、待機中の仕事にもキャンセルを伝える。
  • 共有枠の中で同時実行数と要求開始レートを両方制限する。
  • 待機や再試行に入る前に、完了した応答の資源を解放する。
  • 枠を使い切った場合や恒久的な失敗では停止する。
  • 試行回数と最終結果を記録し、監視で再試行を把握できるようにする。

小さく制御したバッチで修正を検証する

件数を追跡できる少数の読み取りから始め、初回試行、再試行、成功、最終失敗を記録します。実際の開始間隔と実行中件数が計画どおりか確認します。その後、既知の Retry-After を持つ 429 を模擬し、実サービスに繰り返し負荷をかけずに待機ロジックを調べます。

要求レート計算機で秒と分の単位を換算し、同時実行数計算機で遅延の仮定を確認します。結果を実際のサービス上限と比較します。429 が残る場合は、待機を盲目的に増やす前に、共有している呼び出し元と割り当ての種類を調べます。

よくある質問

429 は IP が禁止されたという意味ですか?

必ずしもそうではありません。レート制限を示し、対象はアカウント、トークン、経路、IP、サービス全体などです。応答詳細とサービス資料を読んでから対策を選びます。

Retry-After がなければ直ちに再試行しますか?

ヘッダーがないことは即時再試行の指示ではありません。公開された規則、または上限付きバックオフとジッターを使い、総試行回数を共有範囲で制限します。

ワーカーを増やせば要求過多は解決しますか?

共有枠への圧力が増えることがあります。まず制限の対象を特定し、キューと同時実行を調整します。契約上追加容量が許されている場合に限り、増強が役立ちます。

出典と定義

計算方法の確認日: