先に要点
- ポーリング(polling)とは、クライアントが「更新ありますか?」とサーバーへ定期的に問い合わせて、最新情報を取りに行く方式。一定間隔でリクエストを繰り返すのが基本形(定期ポーリング / short polling)。
- 最大のメリットは実装がシンプルで、普通の HTTP リクエストだけで成立すること。サーバーもクライアントも特別な仕組みが要らない。デメリットは間隔が短いほどサーバー負荷と通信量が増え、間隔が長いほど反映が遅れること。
- ロングポーリング(long polling)は「更新が来るまでサーバーが応答を保留する」改良版。無駄な空振りリクエストを減らせるが、接続を長く掴むぶん別の負荷がある。
- リアルタイム性が要るならSSE(サーバー→クライアントの一方向)・WebSocket(双方向)、サーバー間のイベント通知ならWebhook(相手から呼んでもらう)が向く。これらは「ポーリングの上位互換」ではなく、用途が違う別の選択肢。
- 選ぶ基準は「どれくらいの速さで反映したいか(リアルタイム性)」「サーバー負荷・通信量をどこまで許せるか」「実装・運用コスト」の 3 つ。数十秒〜数分の遅延が許されるなら、ポーリングが最も堅実で安いことが多い。
「画面に最新の状態を出したいけど、ポーリングでいいの? それとも WebSocket?」── リアルタイムっぽい機能を作るとき、最初に迷うのがこの「更新の取り方」です。選択肢が複数あって、それぞれ向き不向きがあるため、なんとなく WebSocket を選んで運用で苦労する、という失敗がよくあります。
この記事では、まず基本である ポーリング を押さえたうえで、ロングポーリング・SSE・WebSocket・Webhook の違いと使い分けを、リアルタイム性・サーバー負荷・実装コストの観点で整理します。WebSocket 単体の詳細は WebSocketとは?HTTPとの違いとリアルタイム通信の使いどころ、Webhook 単体は Webhookとは?APIとの違い・よくある使い方・実務の注意点 でも扱っています。
ポーリングとは — まず一言で
ポーリング(polling)とは、クライアントが一定間隔でサーバーに「更新ありますか?」と問い合わせ、新しいデータがあれば受け取る方式です。日本語では「定期問い合わせ」「巡回」などと訳されます。
身近な例だと、「メールアプリが 5 分おきに新着をチェックする」「在庫ページが 30 秒おきに残数を更新する」のような動きがポーリングです。サーバーから勝手に届くのではなく、クライアント側が能動的に取りに行くのがポイントです。
基本形(short polling)
「○秒ごとにリクエストを送る」のが最も単純な定期ポーリング。普通の HTTP リクエストを繰り返すだけなので、サーバーもクライアントも特別な実装が要らない。
クライアント主導
「いつ取りに行くか」をクライアントが決める。サーバーは聞かれたときに「今の状態」を返すだけでよく、誰が今つながっているかを覚えておく必要がない(状態を持たない)。
空振りが起きる
更新がなくても問い合わせるので、「変化なし」という無駄なやり取りが大量に発生しやすい。間隔が短いほど空振りも増える。これがポーリングの一番のコスト。
遅延は間隔しだい
30 秒間隔なら、最悪 30 秒前のデータを見ていることになる。反映の速さは問い合わせ間隔で決まる。速くしたいほど負荷が上がるトレードオフがある。
ポーリングのメリットとデメリット
ポーリングを選ぶかどうかは、この長所と短所のバランスで決まります。
実務で効くのは 「空振りリクエストのコスト」です。たとえば 1 万人のユーザーが 5 秒間隔でポーリングすると、更新がほとんどなくても毎秒 2,000 リクエストがサーバーに飛びます。レート制限や課金が絡む外部 API を相手にポーリングすると、ここで一気にコストが膨らみます。
逆に言えば、「数十秒〜数分の遅延が許される」「クライアント数が限られている」なら、ポーリングは最もシンプルで壊れにくい選択肢です。リアルタイム性を過剰に追わないことが、運用コストを下げるコツです。
ロングポーリングとの違い
ポーリングの「空振りが多い」弱点を改良したのが ロングポーリング(long polling) です。
| 観点 | 定期ポーリング(short polling) | ロングポーリング(long polling) |
|---|---|---|
| サーバーの応答 | 聞かれたら即座に「今の状態」を返す | 更新が出るまで応答を保留し、出たら返す |
| 空振り | 更新がなくても毎回応答(空振り多い) | 空振りが大幅に減る |
| 反映の速さ | 次の問い合わせまで遅れる | 更新が出た瞬間に近い |
| サーバーの負担 | リクエスト数は多いが 1 本は短い | リクエスト数は減るが接続を長く掴む |
| 実装の複雑さ | とても簡単 | タイムアウトと再接続の設計が必要 |
ロングポーリングは「更新が出るまでサーバーが待つ」ので、定期ポーリングよりリアルタイム性が高く、空振りも減るのが利点です。一方で、サーバーは多数の接続を保留したまま抱えることになり、リバースプロキシやロードバランサーのタイムアウト設定とぶつかりやすくなります。AWS の SQS のロングポーリングも同じ発想で、空のレスポンスを減らしてコストと無駄な取得を抑える仕組みです。
ポーリング / SSE / WebSocket / Webhook の使い分け
「更新の取り方」には、ポーリング以外にも選択肢があります。混同されやすいので、まず全体像を一枚で押さえます。
| 方式 | 方向 | リアルタイム性 | 向く場面 |
|---|---|---|---|
| 定期ポーリング | クライアント→サーバー(取りに行く) | 低(間隔しだい) | 数十秒の遅延が許される更新確認 |
| ロングポーリング | クライアント→サーバー(待つ) | 中〜高 | WebSocket を使えない環境での準リアルタイム |
| SSE(Server-Sent Events) | サーバー→クライアント(一方向) | 高 | 通知・進捗・株価のような配信 |
| WebSocket | 双方向 | 高 | チャット・共同編集・ゲーム |
| Webhook | サーバー→サーバー(相手が呼ぶ) | 高(イベント発生時) | 外部サービスからのイベント連携 |
ここで一番大事な誤解の解消が、「SSE / WebSocket / Webhook はポーリングの上位互換ではない」という点です。それぞれ通信の方向と前提が違う、別の道具です。
SSE は「一方向の配信」
SSE は、サーバーからクライアントへ一方向にデータを流し続ける仕組み。通知や進捗バー、AI の逐次出力(ストリーミング)のように「サーバーから届けるだけでよい」場面に向く。HTTP の上で動くので WebSocket より導入が軽い。
WebSocket は「双方向」
WebSocket は、接続を開いたまま双方向にメッセージを送り合える。チャット・共同編集・対戦ゲームのように「クライアントからもサーバーからも、すぐ送りたい」場面の本命。そのぶん運用は重い。
Webhook は「サーバー間通知」
Webhook は、イベントが起きたときに相手サーバーへ HTTP で通知してもらう仕組み。決済完了や CI 完了など「外部サービスのイベントを受け取る」用途。ブラウザの画面更新とは別レイヤーの話。
ポーリングは「土台」
上記が使えない / 過剰なときの堅実な土台がポーリング。「まずポーリングで作り、必要な部分だけ高度な方式に置き換える」のが現実的な進め方。最初から全部 WebSocket にしない。
どう選ぶか — 判断の手順
実務では、次の順番で考えると迷いにくくなります。
判断の核は 「リアルタイム性は要件であって、目的ではない」ことです。速ければ速いほど良いわけではなく、速さには負荷・実装・運用のコストが必ず付きます。「数十秒の遅延でユーザーが困らない」なら、ポーリングを選ぶのが最もコスパの良い判断になることは多いです。
フロントエンドでのポーリング実装の注意点
実際にポーリングを実装するときに、つまずきやすいポイントを挙げます。
画面が非表示なら止める
タブが裏に回っているのにポーリングし続けると、負荷の無駄。ブラウザの「ページの表示状態が変わったとき」のイベントを使って、非表示のときはポーリングを止める / 間隔を伸ばすのが定石。
前の応答を待ってから次へ
固定間隔で機械的に投げると、応答が遅いときにリクエストが渋滞する。「応答が返ってから次の問い合わせを始める」形にして、重なりを防ぐ。
エラー時はバックオフ
サーバーが落ちているときに同じ間隔で叩き続けると追い打ちになる。失敗が続いたら間隔を徐々に伸ばす(指数バックオフ)のが安全。レート制限対策とも共通する考え方。
差分だけ取る
毎回全件を返すと通信量が膨らむ。「前回以降の更新だけ」を返す設計(更新時刻やカーソルを渡す)にすると、ポーリングでも通信量を大きく抑えられる。
なお、React の TanStack Query のようなデータ取得ライブラリには、一定間隔で自動再取得する仕組み(refetchInterval)が用意されており、上記の「重なり防止」「裏タブで停止」もある程度ライブラリ側で面倒を見てくれます。自前で setInterval を回す前に、使っているライブラリの機能を確認すると実装がシンプルになります。
ポーリングに関するよくある質問
Q. ポーリングとロングポーリングはどちらが優れていますか?
A. 状況によります。実装の簡単さなら定期ポーリング、リアルタイム性と空振り削減ならロングポーリングです。ただしロングポーリングは接続を長く掴むため、プロキシやロードバランサーのタイムアウト設計が必要になります。「数十秒の遅延が許されるなら定期ポーリング、もっと速くしたいが WebSocket は重い、という中間でロングポーリング」と考えると選びやすいです。
Q. ポーリングは時代遅れですか? WebSocket を使うべきですか?
A. 時代遅れではありません。WebSocket は双方向・低遅延が必要な場面では強力ですが、接続維持・再接続・スケール・監視の負担が増えます。「数十秒の遅延で十分」「サーバーから届けたいだけ」なら、ポーリングや SSE のほうが実装も運用もシンプルで堅実です。要件に対して過剰な方式を選ばないことが大切です。
Q. ポーリングの間隔はどれくらいにすべきですか?
A. 「許容できる遅延」と「サーバー負荷」から逆算します。ユーザーが 1 分の遅れを許せるなら 30〜60 秒で十分なことが多いです。間隔を短くするほどリアルタイムに近づきますが、リクエスト数は反比例で増えます。外部 API を叩く場合はレート制限と課金も考慮し、必要以上に短くしないのが鉄則です。
Q. SSE と WebSocket はどう違いますか?
A. SSE はサーバーからクライアントへの一方向、WebSocket は双方向です。通知・進捗・AI の逐次出力のように「サーバーから流すだけ」なら、HTTP の上で動く SSE のほうが軽量です。チャットや共同編集のように「クライアントからもリアルタイムに送りたい」なら WebSocket が必要になります。
Q. Webhook はポーリングの代わりになりますか?
A. 用途が重なる場面もありますが、別物です。Webhook は「イベントが起きたら相手サーバーから通知してもらう」サーバー間の仕組みで、ブラウザの画面更新には直接使えません。外部サービス(決済、CI、Git など)のイベントを受け取るなら Webhook、自分の画面に最新状態を反映するならポーリングや SSE、と役割で分けて考えます。
Q. ポーリングでサーバー負荷を抑えるコツは?
A. 間隔を必要十分に長くし、差分だけ返し、裏タブでは止めるのが基本です。加えて、応答が返ってから次を投げる(重なり防止)、エラー時は指数バックオフ、キャッシュやレスポンスの圧縮を使う、といった工夫で大きく負荷を下げられます。「全件を短間隔で取りに行く」が最も負荷が高いアンチパターンです。
Q. まず何から作ればいいですか?
A. ポーリングから始めるのが無難です。普通の HTTP リクエストだけで成立し、壊れにくく、後から差し替えやすいからです。運用してみて「この画面だけ遅延が問題」と分かったら、その画面だけ SSE や WebSocket に置き換えます。最初から全部リアルタイム方式で作ると、運用の難易度だけ上がって後悔しやすいです。
まとめ
ポーリングは 「クライアントが定期的にサーバーへ更新を問い合わせて取りに行く」、最もシンプルで堅実な更新の取り方です。実装が簡単でステートレスに作れる反面、間隔を短くすると空振りリクエストでサーバー負荷と通信量が増えます。
リアルタイム性が要るなら、空振りを減らすロングポーリング、サーバーからの一方向配信なら SSE、双方向なら WebSocket、外部サービスのイベント連携なら Webhook と、方向と要件で道具を選び分けるのが正解です。これらはポーリングの上位互換ではなく、用途の違う別の選択肢です。
実務での鉄則は 「許容できる遅延を最初に決め、過剰なリアルタイム性を追わない」こと。数十秒の遅延で困らないなら、ポーリングが最も安く壊れにくい選択になります。「まずポーリングで作り、本当に必要な画面だけ高度化する」のが、運用で後悔しない進め方です。
参考リンク
- MDN: Server-sent events
- MDN: The WebSocket API
- AWS Docs: Amazon SQS short and long polling
- MDN: Page Visibility API