YouTubeを何度もリロードしたり、APIを使ったアプリを作っていたら突然「429 Too Many Requests」というエラーが出てきたり、「なんで急に使えなくなるの?」って思ったことない?あれって実は「レート制限」というルールが動いているんだよ。この記事を読めば、レート制限がなぜ必要なのか・どんな仕組みなのか・どう付き合えばいいのかが全部わかるよ。
- レート制限とは、一定時間内に送れるリクエスト数に上限を設ける仕組みで、サーバーへの過負荷を防ぐためにある。
- 制限に引っかかるとHTTPステータス429が返り、しばらく待てば再度リクエストできるようになる。
- プログラムでは指数バックオフを使って、失敗のたびに待ち時間を増やしながら安全に再試行するのが定石だよ。
もうちょっと詳しく
レート制限は「時間の窓」の考え方で動いていることが多い。たとえば「1分間に60回まで」という制限なら、その60秒間のあいだにリクエストが60回を超えた瞬間にブロックされる。これを固定ウィンドウ方式という。一方、「直近60秒の中で常に60回以内」という方式をスライディングウィンドウ方式といって、より細かく制御できる。どちらの方式を使っているかはサービスによって違うけど、ユーザー目線では「制限に引っかかったら待つ」という対処法は同じだよ。また制限の単位もいろいろで、IPアドレス単位・アカウント単位・APIキー単位など、サービスによってさまざま。無料プランと有料プランで上限が違うことも多い。
制限の単位(IPか?アカウントか?)を確認するだけで対策が変わるよ!
⚠️ よくある勘違い
→ 悪意がなくても、ループ処理や並列処理のちょっとしたミスで簡単に引っかかる。初心者だから・上級者だからという話じゃないんだよ。
→ 大事なのは引っかかった後の対処法(待ち時間の設定・バックオフ実装)を知っておくこと。429が出たら慌てずに待てばOKだよ。
[toc]
レート制限ってそもそも何?
「使いすぎ」を止める番人
レート制限(Rate Limit)を一言でいうと、「一定の時間内に送れるリクエストの数を制限する仕組み」だよ。「レート」は「速さ・頻度」、「制限」はそのまま「上限を設ける」という意味。つまりレート制限とは「一定の速さ・頻度を超えてリクエストを送れないようにするルール」ということ。
身近な例で考えてみよう。コンビニのATMには「1日に引き出せる金額の上限」があるよね。あれは銀行を守るための制限。レート制限はそれのインターネット版で、「1分間に何回までAPIを呼んでいいか」「1時間に何回まで検索できるか」という上限をサーバー側が設けているんだ。
どんなサービスに付いている?
レート制限はほぼすべてのWebサービス・APIに付いている。代表的な例を見てみよう。
- Twitter(X)API:無料プランでは1か月に読み込めるツイート数に上限がある
- OpenAI API:1分あたりのトークン数・リクエスト数に制限がある
- Google Maps API:1秒あたりのリクエスト数に制限がある
- GitHubAPI:認証なしなら1時間60回、認証ありなら5000回まで
- YouTube Data API:1日あたりのクォータ(つまり使える”ポイント”のようなもの)が決まっている
有名なサービスはほぼ全部なんらかのレート制限を持っていると思っておいていいよ。制限の内容(何回まで・何の単位で・どれくらいの時間で)はサービスごとにバラバラだから、使う前に必ずドキュメントを確認しよう。
制限の「単位」はいろいろある
レート制限には「何を基準にカウントするか」という単位がある。主に3種類あるよ。
- IPアドレス単位:同じネットワークからのアクセスをまとめてカウントする。学校や会社のWi-Fiは複数人が同じIPを使うこともあるため、1人が制限に引っかかると他の人も巻き込まれることがある
- アカウント・APIキー単位:ログインしているユーザーや発行されたAPIキーごとにカウントする。一番よくある方式
- エンドポイント単位:「検索API」「投稿API」など、機能ごとに別々に制限がある。検索は1分10回・投稿は1分5回、みたいな感じ
なぜレート制限が必要なの?
サーバーはみんなで使う共有物
インターネットのサーバーは、世界中の大勢の人が同時に使う「共有の場所」だよ。学校の体育館みたいなもので、1クラスが全部のスペースを独占したら他のクラスが全然使えなくなるよね。サーバーも同じで、1人のユーザーが大量のリクエストを送ると、サーバーの処理能力がいっぱいになって他の全員が遅くなる・使えなくなるという状況が起きる。
レート制限はこれを防ぐためにある。「1人が使えるのは○回まで」と決めることで、みんなが公平にサービスを使えるようにしているんだ。
悪意ある攻撃からも守ってくれる
レート制限がない世界では、攻撃者が大量のリクエストをサーバーに送りつけて意図的にダウンさせる「DDoS攻撃(つまり、サーバーをリクエストで溺れさせてサービス停止に追い込む攻撃のこと)」がやりたい放題になってしまう。レート制限をかけることで、1つのIPや1つのアカウントから異常な量のリクエストが来ても自動的にブロックできるんだ。
また、ログインページへの大量アクセス(パスワードを総当たりで試す攻撃)なども、レート制限があれば一定回数を超えた時点でブロックできるので、セキュリティ対策としても重要な仕組みだよ。
コストの公平な分配
APIを無料で提供しているサービスでも、サーバーを動かすコストは当然かかる。1人のユーザーが無制限に使い続けたら、サービス提供者が損をしてしまう。だから「無料プランは1日○回まで、それ以上使いたければ有料プランへ」という形でビジネスモデルとしてもレート制限が機能しているんだよ。
レート制限の仕組み・アルゴリズム
固定ウィンドウ方式
一番シンプルな方式が「固定ウィンドウ(Fixed Window)」。つまり「ある決まった時間の区切りの中でカウントする」という方法のこと。
たとえば「1分間に10回まで」という制限なら、0秒〜60秒の間に10回を超えたらブロック。61秒になったらカウンターがリセットされてまた10回使えるようになる。わかりやすいけど欠点もあって、59秒に10回送って、61秒にまた10回送ると、2秒間で20回送れてしまう「リセット直後の瞬間的な大量送信」が起きやすい。
スライディングウィンドウ方式
固定ウィンドウの欠点を補うのが「スライディングウィンドウ(Sliding Window)」。つまり「直近○秒間のリクエスト数を常に数え続ける」という方法のこと。
常に「今から過去60秒間のリクエスト数」を見続けるので、リセットの瞬間に一気に送るズルが通じない。より公平で正確だけど、サーバー側の実装がちょっと複雑になるよ。
トークンバケット方式
よく使われるもう一つの方式が「トークンバケット(Token Bucket)」。つまり「バケツの中にトークン(許可証)が一定速度で溜まっていき、リクエストのたびに1枚消費する」という方法のこと。
バケツがいっぱいになったらそれ以上トークンは溜まらない。トークンがなければリクエストは弾かれる。普段はあまり送らない人はトークンが溜まるので、たまに多めに送ることができる。APIをたまにしか使わない人には優しい仕組みだよ。
制限に引っかかったときの対処法
エラーの読み方
レート制限に引っかかると、サーバーから「429 Too Many Requests」というHTTPステータスコードが返ってくる。HTTPステータスコードとは、つまりサーバーが「今の状態」を数字3桁で教えてくれる信号のこと。200は「成功」、404は「見つからない」、そして429は「送りすぎ」だよ。
このとき一緒に返ってくるレスポンスヘッダー(つまりサーバーからの「付箋メモ」のようなもの)にも注目しよう。よく使われる情報はこんな感じ。
- X-RateLimit-Limit:制限の上限(例:60)
- X-RateLimit-Remaining:あと何回送れるか(例:0)
- X-RateLimit-Reset:制限がリセットされる時刻(UNIX時間で記載されることが多い)
- Retry-After:何秒後に再送してよいか(例:30)
指数バックオフ(Exponential Backoff)
429が返ってきたとき、プログラムがすぐ再送するとまた制限に引っかかる。だから「失敗したら少し待ってから再送する」という処理が必要で、これをリトライ処理という。
その中でも特によく使われるのが「指数バックオフ(Exponential Backoff)」。つまり「失敗するたびに待ち時間を2倍・4倍・8倍と増やしていく方法」のこと。
具体的にはこんなイメージ。
- 1回目の失敗 → 1秒待って再送
- 2回目の失敗 → 2秒待って再送
- 3回目の失敗 → 4秒待って再送
- 4回目の失敗 → 8秒待って再送
- 5回目の失敗 → 諦めてエラーを返す
こうすることで、サーバーが混雑しているときに一斉に再送することを防げるんだ。さらに「ジッター(つまりランダムな揺らぎのこと)」を待ち時間に加えると、複数のユーザーが同じタイミングで再送するのも防げる。
制限を避けるための設計テクニック
引っかかってから対処するだけでなく、最初から制限に引っかかりにくいプログラムを作る工夫もできるよ。
- キャッシュを使う:同じデータを何度もAPIから取得するのではなく、1回取得したら保存しておいて次からはそれを使う。リクエスト数を大幅に減らせるよ
- バッチ処理にまとめる:100件のデータをバラバラに100回リクエストするのではなく、まとめて1回のリクエストで取得できる設計にする
- リクエストの間に待ち時間を入れる:ループ処理の中に「1秒待つ」を入れるだけで、大量送信を防げる
- 事前にレスポンスヘッダーを確認する:残りリクエスト数(X-RateLimit-Remaining)が少なくなったら、リセットまで自主的に待つ
日常のサービスでも見かけるレート制限
SNSの投稿・いいね制限
「Twitterで大量にフォローしたらアカウントが一時停止された」「Instagramでいいねしまくったら止められた」という経験はない?あれもレート制限だよ。スパムアカウントが大量に自動操作するのを防ぐために、1日あたりの操作回数に上限が設けられているんだ。
人間が普通に使う分には引っかからない量に設定されていることが多いので、引っかかったとしたら「それはちょっと使いすぎだよ」というサービスからのサインかもしれないよ。
ログイン試行の回数制限
「パスワードを何度も間違えたらアカウントがロックされた」という経験もレート制限の一種。これは「パスワードを総当たりで試す攻撃(ブルートフォース攻撃)」を防ぐためのセキュリティ機能でもある。
「5回間違えたら30分ロック」のように、ユーザーを守るためにあえて不便にしているんだよ。
検索エンジンのクロール制限
GoogleのようなサービスはWebサイトを自動的に巡回(クロール)してデータを収集するけど、サイト側から見ると大量のリクエストが来ることになる。だからWebサイトは「robots.txt」というファイルで「Googleのクローラーは1秒1回だけアクセスしてね」というレート制限をかけることができるんだ。
このように、レート制限はAPIだけの話ではなく、Webの世界全体でいたるところに使われている仕組みなんだよ。
