APIレート制限とは
APIレート制限(Rate Limiting)とは、一定時間内に受け付けるAPIリクエスト数に上限を設ける仕組みです。APIプロバイダーが過負荷からシステムを守り、全ユーザーに均等なサービスを提供するために実施します。例えば「1分間に60リクエストまで」「1日あたり10,000リクエストまで」といった制限が設けられます。
利用者としてはレート制限の存在を理解し、制限内で効率よくAPIを活用することが求められます。また、自社でAPIを提供する場合は適切なレート制限の設計がシステムの安定性を保つ鍵となります。
レート制限の主要アルゴリズム
1. 固定ウィンドウカウンター
最もシンプルな方式です。「1分間に100リクエスト」という制限の場合、毎分0秒にカウンターをリセットします。実装が簡単ですが、ウィンドウの境界付近に大量のリクエストが集中する「バーストアタック」に弱いという欠点があります。
2. スライディングウィンドウログ
直近N分間のリクエストタイムスタンプを記録し、現在時刻から遡ってN分以内のリクエスト数をカウントします。固定ウィンドウより公平ですが、メモリ使用量が多くなります。
3. スライディングウィンドウカウンター
固定ウィンドウカウンターとスライディングウィンドウの折衷案です。前のウィンドウと現在ウィンドウのカウントを重みで合算することで、バースト問題を軽減しながらメモリ効率を保ちます。
4. トークンバケット
バケツにトークンが一定速度で補充され、リクエストごとにトークンを消費する方式です。バケツが満杯の状態でリクエストが少ない時間帯が続いた後、一定のバーストを許容できるのが特徴です。AWS API GatewayやStripeが採用しています。
5. リーキーバケット
リクエストをキューに入れ、一定速度でキューから取り出して処理する方式です。出力レートが一定のため、バックエンドへの負荷が均等になります。
レート制限の種類
APIによって、制限のかかり方が異なります。
- ユーザー単位:同一APIキー・アカウントからのリクエスト数を制限
- IPアドレス単位:同一IPからのリクエスト数を制限(プロキシ経由の場合に有効)
- エンドポイント単位:特定のAPIエンドポイントごとに個別の制限を設定
- グローバル制限:サービス全体のリクエスト数上限
レート制限を確認するためのレスポンスヘッダー
多くのAPIはレスポンスヘッダーでレート制限の状態を通知します。
X-RateLimit-Limit:制限の上限値X-RateLimit-Remaining:現在の残りリクエスト数X-RateLimit-Reset:制限がリセットされるUNIXタイムスタンプRetry-After:429返却時に、何秒後に再試行すべきかを示す
これらのヘッダーを監視することで、制限到達前に速度を自動調整するレート制限対応クライアントを実装できます。
レート制限対策のベストプラクティス
1. エクスポネンシャルバックオフ(指数バックオフ)
429エラーが返ったときに、リトライ間隔を指数関数的に増やして再試行します。1秒→2秒→4秒→8秒と間隔を倍増させ、ランダムなジッターを加えることでリトライの集中を防ぎます。
2. リクエストキューイング
一定時間あたりのリクエスト数が上限を超えないよう、キューを使ってリクエストを順次送信します。p-limitなどのライブラリが役立ちます。
3. キャッシュの活用
同じデータを繰り返し取得する場合はキャッシュを使い、不要なAPIリクエストを削減します。Redis・Memcachedのようなインメモリキャッシュが有効です。
4. バッチリクエスト
APIが複数件の一括取得(バルクエンドポイント)を提供している場合は活用しましょう。100件のデータを1件ずつ取得する代わりに、1リクエストで100件まとめて取得することで効率化できます。
5. Webhookへの移行
「変更を検知したい」というポーリング用途であれば、APIがWebhookをサポートしている場合はそちらに移行することで、不要なリクエストを大幅に削減できます。
自社APIにレート制限を実装する場合
自社でAPIを公開する際は、適切なレート制限の設計が不可欠です。考慮すべきポイントは以下の通りです。
- 無料・有料プランで異なる上限を設ける
- 超過時の429レスポンスにRetry-Afterヘッダーを含める
- APIゲートウェイ(Kong・AWS API Gateway等)でレート制限機能を活用する
- DDoS対策としてグローバルレート制限も設定する
まとめ
APIレート制限はシステムの安定運用に欠かせない仕組みです。利用者としては、エクスポネンシャルバックオフ・キャッシュ・バッチリクエストを活用して制限内で効率よくAPIを使いましょう。提供者としては、ユーザーの利便性とシステム保護のバランスを取りながら、適切な制限値と明確なエラーメッセージを設計することが重要です。