MeWrite Docs

HTTP 429: Too Many Requests

レート制限エラーの解決方法

概要

APIのレート制限を超えた場合に返されるHTTPステータスコードです。

エラーメッセージ

HTTP/1.1 429 Too Many Requests
Retry-After: 60

原因

  1. リクエスト過多: 短時間に多数のリクエスト
  2. 並列処理: 同時リクエストが多い
  3. ループ内のAPI呼び出し: 制限を考慮していない
  4. 共有クォータ: 他のユーザーとクォータ共有

解決策

1. Retry-Afterを尊重

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
async function fetchWithRetry(url, options = {}) {
  const response = await fetch(url, options);

  if (response.status === 429) {
    const retryAfter = response.headers.get('Retry-After') || 60;
    await sleep(parseInt(retryAfter) * 1000);
    return fetchWithRetry(url, options);
  }

  return response;
}

2. レートリミッター実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class RateLimiter {
  constructor(requestsPerSecond) {
    this.queue = [];
    this.interval = 1000 / requestsPerSecond;
    this.lastRequest = 0;
  }

  async schedule(fn) {
    const now = Date.now();
    const wait = Math.max(0, this.lastRequest + this.interval - now);
    this.lastRequest = now + wait;
    await sleep(wait);
    return fn();
  }
}

const limiter = new RateLimiter(10);  // 10 req/s
await limiter.schedule(() => fetch(url));

3. Bottleneckライブラリ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import Bottleneck from 'bottleneck';

const limiter = new Bottleneck({
  reservoir: 100,        // 初期トークン
  reservoirRefreshAmount: 100,
  reservoirRefreshInterval: 60 * 1000,  // 1分ごとにリセット
  maxConcurrent: 5
});

const result = await limiter.schedule(() => fetch(url));

よくある間違い

  • Retry-Afterヘッダーを無視
  • エクスポネンシャルバックオフなし

HTTP の他のエラー

最終更新: 2025-12-09