429 Too Many Requests とは?原因と対処法
429 Too Many Requests は、短時間にリクエストを送りすぎてサーバーの レート制限に達したことを示すHTTPステータスです。利用者、APIキー、IPアドレスなどに 設定された上限が働いており、必ずしもサーバー障害ではありません。
HTTP 429 means the client exceeded a rate limit. The correct retry time depends on the response headers and the provider's quota policy.
TL;DR
- 短時間に送りすぎて、回数・同時実行数・クォータの上限に達した状態です。
Retry-Afterまたはドキュメントの制限値に従い、間隔を空けて再試行します。- 指数バックオフとジッターを使い、即時リトライの連打を避けます。
- 頻発するならバッチ化、キャッシュ、キュー、並列数制限で呼び出しを減らします。
1. 利用者・クライアント開発者側の解決方法
ブラウザでは連続更新を止めて数分待ちます。APIクライアントではレスポンスヘッダを保存し、 いつ解除されるか、どの単位の制限に達したかを判断してください。
| ヘッダ | 意味 | 対応 |
|---|---|---|
Retry-After: 60 | 60秒後に再試行可能 | 60秒以上待つ |
Retry-After: 日時 | 指定日時以降に再試行 | 時計の差も考慮 |
X-RateLimit-Limit | 時間枠内の上限 | 送信ペースを抑える |
X-RateLimit-Remaining | 残り回数 | ゼロになる前に抑制 |
X-RateLimit-Reset | リセット時刻 | 形式を仕様書で確認 |
Retry-After には秒数とHTTP日時の2形式があります。X-RateLimit-* はサービスごとに意味が異なり、標準化されたRateLimit 系を使うAPIもあるため、公式ドキュメントを優先します。
429はいつ解除される?
Retry-Afterがあれば、その時間に小さな余裕を加えて待つ。- 無ければリセット時刻やAPIの「毎分」「毎日」の制限を確認する。
- 情報が無ければ数秒から始め、失敗のたびに待ち時間を増やす。
- 最大試行回数と最大待ち時間を決め、永久に再試行しない。
闇雲な即時リトライはカウンターをさらに消費し、解除を遅らせます。待ち時間をランダムにずらすことも重要です。
2. 指数バックオフとジッターの実装
指数バックオフは試行ごとに待ち時間をおおむね2倍にし、ジッターは乱数を加える方法です。最大試行回数と最大待ち時間を必ず設けます。
JavaScript: fetch
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function fetchWithBackoff(url, options = {}, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
if (attempt === maxAttempts - 1) throw new Error("Maximum retries reached");
const retryAfter = response.headers.get("Retry-After");
const headerDelay = retryAfter && Number.isFinite(Number(retryAfter))
? Number(retryAfter) * 1000
: 0;
const backoff = Math.min(1000 * 2 ** attempt, 30000);
const jitter = Math.random() * 500;
await sleep(Math.max(headerDelay, backoff + jitter));
}
throw new Error("Request failed");
}Python: requests
import random
import time
import requests
def get_with_backoff(url, max_attempts=5):
for attempt in range(max_attempts):
response = requests.get(url, timeout=20)
if response.status_code != 429:
response.raise_for_status()
return response
if attempt == max_attempts - 1:
raise RuntimeError("Maximum retries reached")
retry_after = response.headers.get("Retry-After", "")
header_delay = float(retry_after) if retry_after.isdigit() else 0
backoff = min(2 ** attempt, 30)
jitter = random.random() * 0.5
time.sleep(max(header_delay, backoff + jitter))
raise RuntimeError("Request failed")Exponential backoff reduces pressure on an endpoint, while jitter prevents many workers from retrying at the same moment. Always cap attempts and delay.
3. 生成AI系API・Web APIで429が出る場合
生成AI系APIでは、回数だけでなくトークン数、同時実行数、利用金額にもクォータがあります。 OpenAI、Anthropic、GoogleなどのAPIでも、無料枠や利用ティア、モデルにより分あたりの上限が 異なる場合があります。rate_limit_exceeded が回数上限か課金クォータかを、 レスポンス本文、管理画面、公式ドキュメントで切り分けてください。
| 原因 | 確認先 | 改善策 |
|---|---|---|
| 分あたり回数 | 制限画面・ヘッダ | キューで平準化 |
| トークン量 | 使用量メトリクス | 入力短縮・バッチ化 |
| 同時実行数 | ワーカー設定 | 並列数を制限 |
| 課金クォータ | 請求・契約プラン | 予算やプランを見直す |
同じ結果をキャッシュし、複数件を扱えるAPIではバッチ化します。UI入力はデバウンスし、ジョブはキューから一定速度で取り出します。
4. スクレイピング・自動化での429対策
対象サイトの利用条件と robots.txt を確認し、クロール許可範囲と間隔を尊重します。ページごとに待機を入れ、同一ホストへの並列数を1〜2程度に絞ります。
- 連続アクセスを止め、
Retry-After後に再開する。 - 利用規約、公式APIの有無、クロール方針を確認する。
- ETagや更新日時を利用し、不要な転送を減らす。
- プロキシやIP切り替えで制限を回避しない。
5. サーバー運営者側のレート制限設計
ログインAPIはIPとアカウント、公開APIはAPIキーなど、目的に合う識別キーを使います。正常なバーストまで拒否しないよう平均レートと一時許容量を分けます。
nginx: limit_req
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
add_header Retry-After 1 always;
proxy_pass http://app;
}
}
}この例はIPごとに平均毎秒10リクエスト、バースト20件を許容します。値は処理能力と正規ユーザーの利用パターンを計測して決めます。
Node.js: express-rate-limit
import { rateLimit } from "express-rate-limit";
const apiLimiter = rateLimit({
windowMs: 60 * 1000,
limit: 100,
standardHeaders: "draft-8",
legacyHeaders: false,
handler: (request, response, next, options) => {
response.set("Retry-After", "60");
response.status(options.statusCode).json({
error: "too_many_requests",
message: "Try again later",
});
},
});
app.use("/api", apiLimiter);429には Retry-After を付け、可能なら制限値、残数、リセット時刻も示します。制限イベントを記録し、誤検知率や拒否後の再試行数を監視します。
6. アンチパターン
429を無視して即時リトライを連打する
同じ要求を送り続けると制限時間が延び、他の利用者にも影響します。SDKとアプリの再試行が二重になっていないかも確認します。
多アカウントやIP分散で制限を回避する
アカウント追加、プロキシ、IPローテーションによる意図的な回避は利用規約違反のリスクがあり、アカウント停止や遮断につながります。正式なAPIやクォータ引き上げ申請を利用してください。
すべての429を同じ原因と決めつける
短期制限なら待機で回復しますが、月次予算や契約クォータの枯渇は待機だけでは直りません。レスポンス、管理画面、ログを合わせて判断します。
7. よくある質問 / FAQ
429はどのくらい待てば解除される?
Retry-After が最優先です。無ければ公式の制限値を確認し、数秒から数十秒の指数バックオフで試します。日次クォータなら翌リセットまで解除されない場合があります。
Retry-Afterヘッダが無い場合はどうする?
APIドキュメントとRateLimit系ヘッダを確認します。それも無ければ再試行を少数回に限定し、指数バックオフとジッターを使います。
429と403、BANの違いは?
429は要求回数が多すぎる一時的な制限、403は権限やポリシーによる拒否です。403やBANは原因の解消や運営者への確認が必要です。
8. English summary
429 Too Many Requests indicates that a client exceeded a server-defined rate limit. Honor Retry-After; otherwise consult the API's quota documentation and use capped exponential backoff with random jitter. Reduce request volume through caching, batching, queues, and concurrency limits. Server operators should return actionable rate-limit headers and tune limits from observed traffic.
よくある質問 / FAQ
- 429はどのくらい待てば解除される?
- Retry-Afterに秒数または日時があれば従います。無ければAPIの制限値を確認し、数秒から数十秒待って指数バックオフで再試行します。
- Retry-Afterヘッダが無い場合はどうする?
- 公式ドキュメントとX-RateLimit-Resetなどを確認します。情報が無ければ指数バックオフとジッターを組み合わせます。
- 429と403(BAN)の違いは?
- 429は要求過多で、待つと回復するのが一般的です。403は権限やポリシーによる拒否で、待つだけでは解決しないことがあります。
- APIで429が頻発する時の設計改善は?
- バッチ化、キャッシュ、同時実行数の制限、キューによる平準化、指数バックオフを導入し、必要なら契約クォータを見直します。
- What does 429 Too Many Requests mean?
- HTTP 429 means the client sent too many requests within a server-defined time window. Wait for Retry-After, then retry with exponential backoff and jitter.
- サーバー側は429にどのヘッダを付けるべき?
- Retry-Afterを付け、可能なら制限値、残数、リセット時刻を示すRateLimit系またはX-RateLimit系ヘッダも提供します。