Rate Limitingは後付けできない
KGAのクライアントで、Rate Limiting未実装のAPIが悪意あるスクレイピングにより1時間で500万リクエストを受け、DBが落ちた事例がある。復旧に4時間、ビジネス損失は推定800万円。Rate LimitingはAPI設計のDay 1で組み込むべき機能だ。
アルゴリズム比較
Fixed Window Counter: 最もシンプルだがウィンドウ境界での突発問題あり。Sliding Window Log: 最高精度だがメモリ消費大。Sliding Window Counter: Fixed WindowとSliding Windowの折衷、KGA推奨。Token Bucket: バースト許容量と持続レートを独立制御可能、「通常低頻度、たまにバースト」のパターンに最適。Leaky Bucket: 出力レートが厳密に一定、バックエンド負荷安定化向け。
Redis実装: Sliding Window Counter
キー設計: rate_limit:{user_id}:{window_start}。TTL 120秒(ウィンドウ×2)。Luaスクリプトで現在ウィンドウのINCR、前ウィンドウのGET、加重平均計算をアトミック処理。Redis 1台(4vCPU, 16GB)で毎秒150,000判定、p50 0.15ms、p99 0.8ms。
Token BucketはRedis Hash型で実装。HSET rate_limit:bucket:{user_id} tokens 10 last_refill {timestamp}。ECサイトの例: 通常2-3 req/s、セール時50 req/sバースト。Token Bucket(サイズ50、補充2/s)ならバースト許容しつつ過負荷防止。
分散環境の課題
Gateway Level(Kong、AWS API Gateway等)とService Levelの2層構成をKGA推奨。Gatewayでグローバル制限(DDoS防止)、Serviceでビジネスロジック制限(プラン別)。
Redis ClusterではRate Limitingキーにハッシュタグ({user_id})を付与し、同一ユーザーのキーを同じノードに配置することで正確なカウントを維持する。
レスポンスヘッダー
KGA標準: X-RateLimit-Limit(制限値)、X-RateLimit-Remaining(残数)、X-RateLimit-Reset(リセット時刻Unix timestamp)、Retry-After(429時の待機秒数)。RFCドラフトのRateLimit-Policyも検討したがクライアントSDK対応状況を考慮し従来形式を維持。