レートリミットとは?アルゴリズム5方式と429設計・分散環境の実装を解説【2026年版】

1つのクライアントが毎秒500回APIを呼び、他の利用者のレスポンスが軒並み遅くなる。この種の障害をサーバー増強ではなく入口の制御で止める仕組みが、レートリミット(レート制限)です。本記事では制限単位の決め方、5方式のアルゴリズムの挙動差、429と503の返し分け、Redisで分散カウンタを原子的に扱う実装、アクセスログからしきい値を逆算する手順までを実装者の目線でまとめました。DDoS防御やサーキットブレーカーとの守備範囲、導入を見送るべき条件も条件付きで示します。

まとめ:レートリミットの選定方針としきい値決定の結論

レートリミットは、単位時間あたりのリクエスト数に上限を設けて、1つのクライアントによる占有と誤実装の暴走を入口で止める仕組みです。守るのは可用性と公平性の2点で、悪意ある大量トラフィックの遮断はWAFやDDoS防御の担当になります。

アルゴリズムは用途で決まります。バースト(瞬間的な集中)を許したい公開APIならトークンバケット、下流を一定ペースで守りたいならリーキーバケット、実装を急ぐ社内APIなら固定ウィンドウカウンタで足ります。固定ウィンドウは窓の境界で上限の2倍が通るため、決済や認証など超過が実損につながる経路には向きません。

しきい値は勘で置きません。アクセスログのクライアント別リクエスト数から分位点を出し、p99.9の3〜5倍を上限に、平常時の最大瞬間値を包含する幅をバーストへ割り当てます。導入時は監視のみのドライラン期間を挟み、遮断対象が想定と一致してから本適用へ切り替えてください。

レートリミットの定義と制限単位|スロットリング・クォータとの境界

リクエスト数を時間窓で区切って制限する仕組みと導入する3つの目的

レートリミットは「識別子ごとに、一定時間内で受け付けるリクエスト数の上限を決め、超えた分を拒否または遅延させる」制御です。毎秒10リクエスト、1時間あたり5,000リクエストといった形で表現し、上限に達したクライアントにはHTTPのエラーステータスを返します。

導入する目的は3つ。1つ目は可用性の維持で、特定クライアントの暴走がデータベース接続やワーカースレッドを食い潰す事態を防ぎます。2つ目は公平性の確保。無料プランの利用者が有料プランの応答時間を悪化させる構図を断ちます。3つ目はコスト制御で、従量課金の外部APIや生成AIの推論を挟む経路では、上限がそのまま請求額の天井として効くのです。

制限単位の設計|IPアドレス・APIキー・ユーザーIDの使い分け

何を1クライアントと数えるか。この定義が設計の出発点になります。IPアドレスは認証前のエンドポイントで唯一使える識別子ですが、企業のNAT配下やモバイルキャリアのCGNATでは数千人が同一IPを共有するため、単独で厳しい上限を課すと正規利用者を巻き込みます。ログイン試行の回数制限では、IPとアカウント名の組み合わせを併用する形が実務的です。

認証後はAPIキーやトークンに紐づく契約単位で数えます。さらにエンドポイント単位で上限を分けると精度が上がるのです。一覧取得は毎分600回、レポート生成は毎分5回、といった具合になります。処理コストが2桁違うエンドポイントを同一の上限で括ると、軽い処理には緩すぎ、重い処理には甘すぎる値にしかなりません。

スロットリング・クォータ・輻輳制御との用語上の重なりと実務での違い

スロットリングは超過分を即座に拒否せず遅延させて流量を均す挙動で、レートリミットの実装手段の1つとして語られる用語です。クォータは月間100万リクエストのように、より長い期間の総量に対する割り当てを指します。毎秒の上限と月間総量を同時に課す設計が一般的で、両者は排他ではありません。輻輳制御はTCPの層で送信側が混雑を検知して送出量を調整する仕組みなので、層も主体も別物です。課金連動まで含めるならAPI管理の構成要素の側で整理してください。

アルゴリズム5方式の比較表|精度・メモリ量・バースト許容と適用先

固定ウィンドウカウンタの実装コストの低さと境界で上限2倍が通る欠点

固定ウィンドウカウンタは、時刻を固定長の窓に区切り、窓ごとのカウンタを加算するだけの方式です。キーは「識別子と窓の開始時刻」の組み合わせで、実装はカウンタの加算と有効期限の設定で済みます。メモリはクライアント1つにつき整数1個。導入コストは5方式で最も低く抑えられます。

弱点は窓の境界にあります。毎分60リクエストの上限で、あるクライアントが10時00分59秒に60回、10時01分00秒にさらに60回送ると、実質2秒間で120リクエストが通過してしまうのです。認証試行やクーポン発行のように、超過が金銭や不正に直結する経路では選ばないほうが安全でしょう。

スライディングウィンドウログとカウンタ近似におけるメモリ消費の差

スライディングウィンドウログは、リクエストごとのタイムスタンプを保持し、現在時刻から窓長を引いた時点より古い記録を捨てて残数を数えます。境界の抜けは発生しません。代償はメモリで、消費量が保持中の件数に比例します。毎分1万リクエストを許すクライアントが1,000社いれば、1,000万件分のタイムスタンプを常時抱える計算です。

スライディングウィンドウカウンタは、前の窓と現在の窓の2つのカウンタを持ち、窓内の経過割合で前窓の値を重み付けして加算する近似方式になります。現在の窓が40%経過した時点なら、前窓の値の60%と現窓の値を足して判定する仕組みです。メモリは整数2個、境界の2倍問題も実用上は消えます。多くの公開APIでは、この近似が現実的な落としどころです。

トークンバケットとリーキーバケットでバースト扱いが分かれる理由

トークンバケットは、容量の決まったバケツに一定レートでトークンを補充し、リクエスト1件につき1枚消費する方式です。しばらく無通信だった利用者はトークンを貯め込めるので、容量ぶんのバーストを一度に通せます。補充レートが平均流量、容量が許容バーストという2つのパラメータで挙動を表現でき、利用パターンが読めない公開APIやSDKに向きます。

リーキーバケットは逆に、流入をキューへ溜めて一定レートで漏らす方式です。出力レートが常に一定になるため、下流のデータベースやバッチ処理を守る目的に適します。nginxのngx_http_limit_req_moduleはこの方式で、limit_req_zoneで毎秒のレートを、limit_reqburstで待ち行列の長さを指定します(2026年8月5日時点の公式ドキュメント)。判断は単純です。クライアント体験を優先するならトークンバケット、下流保護を優先するならリーキーバケットを選びます。

実装コスト・精度・メモリ量から5方式を横並びで比較した早見表

5方式の性質を1つの表にまとめます。選定では精度そのものより「境界の抜けが業務上許容できるか」を先に見ると迷いが減ります。

方式 精度 メモリ バースト 向く用途
固定ウィンドウ 低(境界で2倍) 整数1個 制御不可 社内API・暫定導入
スライディングログ 高(抜けなし) 件数に比例 不可 厳格な上限が要る経路
スライディング近似 中〜高 整数2個 ほぼ不可 一般的な公開API
トークンバケット 数値2個 容量ぶん許容 SDK・外部提供API
リーキーバケット キュー長ぶん 平滑化して吸収 DB・バッチの下流保護

429レスポンスとRateLimitヘッダの設計|Retry-Afterの返し方

429と503の使い分け|nginxのlimit_req_statusは既定で503

上限超過で返すステータスは429 Too Many Requests(RFC 6585 第4節で定義)が正解です。503 Service Unavailableはサーバー側の一時的な過負荷や保守を意味し、クライアントから見ると「自分の送りすぎ」なのか「サーバーの不調」なのか区別がつきません。

ここに実装上の落とし穴があります。nginxのlimit_req_statusの既定値は503で、設定を書き足さないかぎり429は返りません(1.29系の公式ドキュメント・2026年8月5日確認)。ゲートウェイでレート制限を有効にしただけで429が返ると思い込んでいると、クライアントのリトライ実装が過負荷用の分岐に流れます。設定ファイルでlimit_req_status 429;を明示してください。

RateLimitヘッダの現状|IETFドラフト版とX-接頭辞の慣用実装

残数をクライアントへ知らせるヘッダは標準化の途中にあります。IETFのhttpapiワーキンググループが進めるdraft-ietf-httpapi-ratelimit-headersは2026年5月更新の第11版が最新で、RFCとしては未発行です(datatracker・2026年8月5日確認)。この案はRateLimitRateLimit-Policyの2フィールドを構造化フィールド構文で表現し、窓長をパラメータwで秒指定します。

実務ではX-RateLimit-Limitのような接頭辞つきの慣用ヘッダが今も広く使われています。GitHubのREST APIはx-ratelimit-limitx-ratelimit-remainingx-ratelimit-resetを返し、未認証で毎時60、個人アクセストークンで毎時5,000という上限を公開しています。回数とは別枠で同時実行100リクエスト、毎分900ポイントという二次レート制限も課しており、処理コストの重いエンドポイントを回数だけで縛らない設計です(公式ドキュメント・2026年8月5日確認)。自社APIでも慣用ヘッダを当面維持し、RFC発行時に新形式を併記できる実装にしておくと移行が楽になります。

Retry-Afterの秒数指定とクライアント側の指数バックオフの実装

429を返すときはRetry-Afterを必ず添えます。値は待機秒数かHTTP-date形式で、リセットまでの残り秒数を入れるのが分かりやすい実装です。これが無いと、クライアントは即座に再送して上限を踏み続けます。

クライアント側はRetry-Afterを第一に尊重し、指定が無い場合のみ指数バックオフに落とします。初回1秒、次に2秒、4秒と倍にしつつ、同時刻に再送が集中しないよう0〜1秒の乱数を足す(ジッターを入れる)実装が定番です。再送する以上、同じ操作が2回適用される可能性は残ります。決済や在庫引当のように二重実行が実損になる経路では、リクエストIDを使った冪等性の担保をセットで設計してください。

分散環境でのカウンタ共有|Redisの原子性とゲートウェイ層への寄せ方

インスタンス単位のカウントで実効上限が台数倍に膨らむ典型的な誤り

アプリケーションのメモリ上にカウンタを持つ実装は、1台構成では正しく動きます。ところが同じアプリを4台へ水平展開した瞬間、各台が独立に上限を数えるため、実効上限は設定値の4倍に膨らみます。オートスケールで台数が変動する構成なら、上限は時間帯ごとに勝手に伸び縮みする状態です。

この誤りは負荷試験で見つかりません。試験環境が1台構成だったり、負荷生成側のIPが固定で全リクエストが同じ台に張り付いたりするからです。解決策は、分散カウンタを外部ストアへ置くか、ゲートウェイ層に制限そのものを寄せるかの二択になります。

RedisのINCRとEXPIREを分けた際のキー永続化とLuaでの原子化

共有ストアにはRedisを使うのが一般的です。ただしINCRでカウンタを加算し、値が1のときだけEXPIREで有効期限を付ける2コマンド構成には落とし穴があります。INCRの直後にプロセスが落ちると有効期限の無いキーが残り、そのクライアントは窓が切り替わっても永久に締め出されるのです。

回避策は2つ。Luaスクリプトで加算と期限設定を1つの原子的操作にまとめるか、SETコマンドのNXEXオプションでキー生成と期限付与を同時に行ってから加算します。トークンバケットのように残トークン数と最終補充時刻の2値を同時に更新する方式では、読み取りと書き込みの間に他プロセスが割り込むため、Luaによる原子化がほぼ必須になります。

ゲートウェイ層とアプリケーション層のどちらで制限をかけるかの基準

判断基準は単純です。識別子が認証前に確定するならゲートウェイ層、認証後のプランや残高に依存するならアプリケーション層に置きます。IPアドレス単位やAPIキー単位の粗い上限はゲートウェイが担い、バックエンドへ到達する前に弾けるぶん効率もよいのです。

一方で「無料プランは毎分60回、法人プランは毎分600回」のようにプラン情報の参照が要る制限は、契約情報を持つアプリケーション側で判定するほうが素直でしょう。ゲートウェイで緩い共通上限、アプリで細かいプラン別上限という二段構えが実務的な構成です。ゲートウェイが担う機能の全体像はAPIゲートウェイの役割と導入判断の側で確認してください。Kong、Envoy、各クラウドのマネージドゲートウェイはいずれもレート制限をプラグインや設定で提供しており、自前実装より先に候補へ入ります。

しきい値の決め方|正常利用の実測分位点から上限とバーストを逆算

アクセスログからクライアント別リクエスト数の分位点を求める手順

上限値を勘で決めると、緩すぎて意味がないか、厳しすぎて正規利用者を切るかのどちらかです。実測から逆算してください。

  1. 直近30日のアクセスログを、制限単位(APIキーやIP)とエンドポイントで分類する
  2. 1分あたりのリクエスト数を時系列で集計し、クライアントごとの系列を作る
  3. 全クライアント横断でp50・p95・p99・p99.9と最大値を求める
  4. 上位の外れ値がどのクライアントかを特定し、正規利用か暴走かを個別に確認する

手順4を飛ばさないでください。分位点の上端は、たいてい特定の1社か1つのバッチ処理によるものです。正規の業務なら上限に含め、実装ミスによる無限ループなら除外して分位点を取り直します。流量の計測指標はREDメソッドによる流量・失敗・所要時間の設計と揃えておくと、導入後の監視にそのまま使えます。

p99.9の数倍を上限に置く根拠と誤検知を避けるバースト幅の決め方

上限値はp99.9の3〜5倍を初期値に置きます。p99.9は「1,000分の1の頻度でしか起きない流量」なので、ここを直接上限にすると月に数回は正規利用者を弾く計算です。3〜5倍の余裕があれば、正常な業務ピークを通しつつ桁違いの暴走だけを捕まえられます。

バースト幅は分位点ではなく最大瞬間値から決めます。1秒粒度で集計した平常時の最大値を包含する幅をトークンバケットの容量へ割り当てれば、日次バッチの開始直後のような正常な集中で誤検知しません。目安は平均レートの10〜30秒ぶんです。平均レートと同程度まで絞ると、リトライが一斉に戻った瞬間に正規利用者を巻き込みます。

段階導入の順序|計測のみのドライラン期間から本適用へ切り替える基準

いきなり遮断を有効にしてはいけません。まず「上限を超えたクライアントをログに記録するだけで通す」ドライランモードで2週間動かします。記録された一覧に想定どおりの相手だけが並んでいるかを確認してください。社内バッチや監視ツールが混じっていたら、別の制限単位へ切り出すか上限を引き上げます。

本適用への切り替え基準は2つ。超過クライアントのうち正規利用者が占める割合が1%を下回っていること。そして超過時のレスポンス処理を主要な社内クライアントが実装済みであること。満たさないまま遮断へ切り替えると、問い合わせ対応で運用が止まります。

DDoS対策・サーキットブレーカーとの守備範囲|導入を見送る条件

レート制限とWAF・DDoS防御が受け持つトラフィック層の違い

レート制限は、識別可能な正当なクライアントが送りすぎる状況を想定した仕組みです。数万の送信元から同時に押し寄せるボリューム型攻撃は、アプリケーションへ到達する前に落とす必要があります。ネットワーク層と輸送層の大量トラフィックはCDNやDDoS防御サービスの担当で、レート制限が肩代わりすることはできません。

逆に、正しいAPIキーを持つ利用者が誤ってループ処理を回した場合、WAFのシグネチャには何も引っかかりません。攻撃パターンではなく流量そのものが問題だからです。両者は直列に並ぶ層で、CDNとDDoS防御を外側に、レート制限をアプリケーションの入口へ置く構成が基本形になります。

サーキットブレーカーとの併用|自衛と下流保護で役割を分ける設計

同じ「流量を絞る」仕組みでも、レート制限とサーキットブレーカーは向きが逆です。レート制限は自分に入ってくる量を制限する入口の防御、サーキットブレーカーは呼び出す先の障害を検知して呼び出しを止める出口の防御になります。実装上は両方を入れるのが正解です。入口で流量を抑え、出口で下流の異常時に素早く諦める。この2つが揃って初めて障害が横に伝播しない構成になります。連鎖障害を止める側の実装はサーキットブレーカーの仕組みと導入判断にまとめてあります。

レート制限の導入を見送るべき3条件と運用で頻発する失敗パターン

導入しないほうがよい場面を3つ挙げます。1つ目は、クライアントが社内システムに限られ、呼び出し元のコードを自分たちで管理できる場合。上限を課すより呼び出し側の実装を直すほうが早く確実です。2つ目は、サーバーレスの従量課金上限が別途効いていてコスト面の天井が既にある場合。3つ目は、1日数千件規模で暴走しても容量に届かない社内向け管理画面になります。

運用で頻発する失敗は3つです。管理者アカウントや監視ツールを制限対象から除外し忘れて障害検知が止まる。ヘルスチェックのエンドポイントに制限がかかりロードバランサが全台を切り離す。そして超過ログを残さないため、問い合わせを受けても遮断か別障害か判別できない。3つ目が最も後を引きます。超過時は識別子・エンドポイント・上限値・実測値の4点を必ずログへ出してください。

受託開発でレート制限をAPI仕様に組み込む際に合意すべき3項目

外部の開発会社とAPIを作る場合、レート制限は仕様書に書かれないまま実装フェーズへ流れがちです。発注時点で3項目を決めておくと後戻りが減ります。制限単位(契約単位かIP単位か)、上限超過時の挙動(429で拒否するか遅延させるか)、そしてクライアント側のリトライ実装の責任範囲です。3つ目が曖昧なまま納品されると、サーバーは正しく429を返すのに利用側が即座に再送し続ける、という噛み合わない構成になります。API設計から上限値の根拠づけ、ゲートウェイ選定までを含めた開発を検討するなら、API開発・システム連携の支援内容をご確認ください。

よくある質問

レートリミットの設計や運用でよく寄せられる疑問を5つ取り上げます。

レートリミットとレート制限は同じ意味ですか?

同じ仕組みを指します。英語のrate limitingに対して、レートリミット、レート制限、流量制限といった訳語が併存している状態です。日本語の資料では「レート制限」、ヘッダ名やライブラリ名では「rate limit」が使われる傾向があります。API仕様書では表記をどちらかに統一してください。

上限超過時は429と503のどちらを返すべきですか?

429を返してください。503はサーバー側の一時的な過負荷や計画停止を表すため、クライアントから見て原因の切り分けができません。注意点として、nginxのlimit_req_statusは既定が503で、設定を書き足さないと429になりません。製品ごとに既定値が異なるので、導入時に実際のレスポンスを確認してください。

レート制限をかけたら正規ユーザーからのエラー報告が増えました。原因は?

まず制限単位を疑ってください。IPアドレス単位で数えていると、企業のNAT配下から接続する複数の従業員が1クライアントとして合算されます。次に上限値の根拠です。分位点を取らずに切りのよい数字を置くと、平常時のピークを下回ることがよくあります。最後にバースト幅で、日次バッチによる瞬間的な集中を吸収できる容量があるかを見てください。

小規模なAPIでもレート制限は導入すべきですか?

公開されているなら導入する価値があります。利用者数が少なくても、認証エンドポイントへの総当たり試行や、外部の生成AI APIを呼ぶ経路の請求額暴走は規模と無関係に起きるからです。社内ネットワークからのみ到達でき呼び出し元も自社管理下なら優先度は下がりますが、認証まわりだけは試行回数の制限を入れてください。

GraphQL APIでもリクエスト数で制限してよいですか?

リクエスト数だけでは足りません。GraphQLは1リクエストで取得するフィールド数やネストの深さを利用者が決められるため、同じ1回でも処理コストが数百倍変わります。クエリの複雑度を事前に算出してポイントとして数え、時間あたりのポイント上限で縛る方式が一般的です。GitHubも毎分2,000ポイントというコストベースの制限を課しています。

関連記事

資料請求

RELATED POSTS 関連記事