MENU

Webhook・ポーリング・WebSocket・SSEの違いとは?クラウドAPI連携でリアルタイム通信を設計する実践ガイド

「外部APIのデータ取得にポーリングを使っているが、リクエスト数が多くてコストがかさんでいる」「Webhookを導入したいが、WebSocketとSSEとの違いが整理できていない」

クラウド上でリアルタイム連携を設計するとき、通信パターンの選択を誤ると後から大規模な改修が必要になります。オンプレ環境ではDBをポーリングするか共有ファイルを監視するかが主流でしたが、クラウドネイティブな設計ではWebhook・WebSocket・SSEなど複数の選択肢があり、それぞれ向き不向きが大きく異なります。

この記事では、クラウドAPI連携で使われる5つの通信パターン(ポーリング・ロングポーリング・Webhook・WebSocket・SSE)の仕組みと違いを、オンプレ経験者にもわかりやすく解説します。AWS上での実装選択肢とユースケース別の判断基準もあわせて整理します。

Webhook・ポーリング・WebSocket・SSEの違いとは?クラウドAPI連携でリアルタイム通信を設計する実践ガイド - 解説

目次

なぜ通信パターンの選択がクラウド設計で重要なのか

オンプレ時代は、アプリケーション間の連携を「定期バッチでDBを確認する」「共有ファイルサーバー上のファイルを監視する」といった方法で実現するケースが多くありました。処理の頻度はせいぜい5分ごと、データ量も予測できる範囲に収まっていたため、ポーリングの非効率さはあまり問題になりませんでした。

クラウド移行後に状況が変わるのは、主に3つの理由からです。

・従量課金: 無駄なリクエストは直接コストに跳ね返ります。ポーリング頻度が高いと、API呼び出し料金がじわじわ積み上がります
・イベント数の増加: クラウドサービスはAPIが細粒度に分割されており、1つのユーザー操作が数十のイベントを生む構造になりがちです
・スケールの非対称性: データを受け取る側と送る側でスケール速度が違うため、通信設計を間違えると片方が詰まって全体が止まります

どのパターンを選ぶかは「リアルタイム性」「サーバー負荷」「実装コスト」「クライアント側の制約」のバランスで決まります。

1. ポーリング(Polling)― 定期的に問い合わせる

最もシンプルな方法で、クライアントが一定間隔でサーバーにリクエストを投げて「何か変わった?」と確認するパターンです。

仕組み

# クライアントが10秒ごとにリクエストを送る GET /api/status → {"updated": false, "data": null} (10秒待機) GET /api/status → {"updated": false, "data": null} (10秒待機) GET /api/status → {"updated": true, "data": {...}}

オンプレ時代にDBのステータスカラムを5分ごとにSELECTする処理と全く同じ発想です。オンプレエンジニアには最も直感的に理解しやすいパターンです。

向いているケース

・リアルタイム性が必要ない(数分の遅延が許容される)
・実装コストを最小限に抑えたい
・クライアント側からしかリクエストできない環境(厳格なファイアウォール内)

問題点

データが変わっていない間も継続的にリクエストが発生するため、「無駄撃ち」が多くなります。間隔を30秒にすれば1日2,880リクエスト、1秒にすれば86,400リクエストです。Amazon API Gatewayの料金(2026年7月時点で100万リクエストあたり$3.50)で換算すると、エンドポイント1つで月数ドルの無駄コストが発生します。システム規模が大きくなるほど影響は無視できなくなります。

2. ロングポーリング(Long Polling)― 答えが来るまで待ち続ける

ポーリングの改良版です。クライアントがリクエストを送った後、サーバーはデータが準備できるまでレスポンスを保留し続け、イベントが発生したタイミングで初めて返答します。

仕組み

# タイムアウトを30秒に設定してリクエスト送信 GET /api/events?timeout=30 # サーバーはイベント発生まで接続を保留(20秒後にイベント発生) → 200 OK: {"event": "order_completed", "id": "12345"} # クライアントはレスポンス受信後、即座に次のリクエストを投げる GET /api/events?timeout=30

向いているケース

・リアルタイム性がある程度必要(秒以内の反応)
・WebSocketが使えない環境(一部のプロキシやロードバランサーが未対応)
・チャットやステータス更新の通知など、頻度が比較的低い用途

問題点

サーバーが大量の接続を同時に保留する必要があるため、コネクション数が圧迫されます。AWS上では、ALBのアイドルタイムアウト(デフォルト60秒)と競合しやすく、ロングポーリングのタイムアウトは「ALBのアイドルタイムアウト-5秒」以内に設定するのが基本です。

3. Webhook ― イベント発生時にサーバーから通知する

ポーリングの発想を逆転させたパターンです。「クライアントが問い合わせる」のではなく、「サーバー側でイベントが起きたときにクライアントの登録URLへPOSTリクエストを送る」仕組みです。

仕組み

# 1. クライアントが受信URLをサービスに事前登録する POST /webhook/register {"url": "https://myapp.example.com/hooks/payment", "secret": "xxx"} # 2. 決済完了イベント発生時、サービスがPOSTを送信する POST https://myapp.example.com/hooks/payment X-Signature: sha256=abcd1234... {"event": "payment.completed", "order_id": "12345", "amount": 5000} # 3. クライアントは200 OKを返す(失敗すると再送される)

向いているケース

・外部サービスとの連携(Stripe決済通知、GitHub Actions、Slack通知など)
・イベント頻度が低く、発生タイミングが不規則
・クライアント側がHTTPSエンドポイントを公開できる環境

AWSでのWebhook活用例

AWS上では、Webhookの受信エンドポイントとしてAmazon API GatewayとAWS Lambdaの組み合わせが定番です。LambdaがリクエストをHMAC検証してからAmazon SQSにキューイングし、ワーカーが非同期処理するパターンが実務で広く使われています。

問題点

クライアントがHTTPSエンドポイントを外部公開できない環境(プライベートVPC内、厳格なファイアウォール内)では使えません。また、送信側のサービスが信頼できるかを検証するためのHMACシグネチャ検証が実装上必須です。さらに、冪等性の考慮も重要で、送信側が「失敗した」と判断して再送した場合に同じイベントを二重処理しないよう、order_idなどの一意キーで処理済みチェックを行う実装が必要です。

4. WebSocket ― 接続を張りっぱなしにして双方向通信する

HTTP接続をアップグレードして双方向の常時接続チャンネルを確立するプロトコルです。一度接続が確立されると、クライアントとサーバーの両方がいつでもデータを送信できます。

仕組み

# 1. WebSocketハンドシェイク(HTTPから昇格) GET /ws HTTP/1.1 Upgrade: websocket Connection: Upgrade → 101 Switching Protocols # 2. 接続確立後、双方向でいつでもデータ送信可能 Server → Client: {"type": "price_update", "value": 150.5} Client → Server: {"type": "subscribe", "symbols": ["USDJPY"]} Server → Client: {"type": "price_update", "value": 150.7} # 3. 明示的に切断するまで接続が維持される

向いているケース

・リアルタイム性が最優先(株価、ゲーム、リアルタイムコラボレーション)
・クライアントとサーバーが頻繁に双方向でメッセージを交換する
・接続確立のオーバーヘッドを最小化してスループットを上げたい

AWSでのWebSocket活用例

Amazon API GatewayはWebSocket APIをネイティブサポートしており、接続管理をマネージドに処理できます。接続ごとにLambdaを呼び出し、接続管理テーブルをDynamoDBに持たせるパターンが標準的です。

注意点として、API Gateway WebSocketは1接続あたりの最大メッセージサイズが128KB、アイドルタイムアウトが10分に設定されているため、長時間の接続維持には定期的なpingフレーム送信が必要です。

問題点

常時接続を維持するため、接続数が増えるとサーバー側のリソースが圧迫されます。オートスケーリング環境では新しいインスタンスに既存の接続が引き継がれないため、Redis Pub/SubやAmazon ElastiCacheを使ってインスタンス間でメッセージをブロードキャストする設計が必要になります。

5. SSE(Server-Sent Events)― サーバーからの単方向プッシュ

HTTP接続を開いたまま維持し、サーバーからクライアントへデータを継続的にストリームするパターンです。WebSocketと異なり、クライアントからサーバーへのメッセージ送信はできません。

仕組み

# クライアントが接続を開く GET /api/stream Accept: text/event-stream # サーバーが継続的にデータを送り続ける(接続は維持したまま) HTTP/1.1 200 OK Content-Type: text/event-stream data: {"type": "progress", "value": 10} data: {"type": "progress", "value": 50} data: {"type": "complete", "result": "success"}

向いているケース

・サーバーからクライアントへの一方向通知で十分(ダッシュボード更新、処理の進捗通知、AIテキスト生成の逐次出力)
・ブラウザから使用する(EventSource APIが標準対応済み)
・WebSocketより実装をシンプルに保ちたい

問題点

HTTP/1.1では1ドメインあたりの同時接続数が最大6つに制限されており、同じドメインへの複数SSE接続がボトルネックになります。HTTP/2を使えば多重化により解消されます。CloudFrontやALBでHTTP/2を有効化することで対応できます。

5つのパターン徹底比較

パターン 通信方向 リアルタイム性 サーバー負荷 主なユースケース
ポーリング クライアント→サーバー 低(間隔依存) 高(無駄リクエスト) 低頻度ステータス確認
ロングポーリング クライアント→サーバー 中(秒以内) 中(接続保留) 通知・チャット
Webhook サーバー→クライアント 高(即時) 低(イベント時のみ) 外部サービス連携
WebSocket 双方向 最高(常時) 中(接続維持コスト) ゲーム・株価・共同編集
SSE サーバー→クライアント 高(即時) 低~中 ダッシュボード・AI出力

AWSでの実装選択肢

AWS SNS / SQS でのWebhookキューイング

Webhookと組み合わせるケースが多いのがAWS SNSとSQSの組み合わせです。外部サービスからWebhookで受け取ったイベントをSQSにキューイングし、ワーカーが非同期に処理するパターンは多くのクラウドネイティブシステムで採用されています。SNSを使えば、同一イベントを複数のSQSキュー(メール送信用・在庫更新用・分析用など)にファンアウトすることも容易です。

AWS EventBridge でのAWSサービス間イベント連携

AWSサービス内でのイベント駆動アーキテクチャにはAWS EventBridgeが適しています。S3へのオブジェクト追加、EC2の状態変化、RDSのスナップショット完了など、AWSサービスが発生させるイベントをWebhookのように受け取って別サービスに転送できます。外部SaaSのWebhookをEventBridgeのパートナーバスで受け取るパターンも普及しています。

Amazon Kinesis での大量ストリーム処理

大量のリアルタイムストリームデータを処理するにはAmazon Kinesisが適しています。IoTデバイスや多数のクライアントからのストリームを受け取り、リアルタイムに集計・分析する用途で活用されます。クライアントからのデータ収集にKinesis Data Streamsを使い、加工済みデータをSSEでダッシュボードに表示する、といった組み合わせが実務でよく見られます。

パターン選択の判断フロー

実際の設計で迷ったときは、以下の順番で判断すると整理しやすいです。

・双方向通信が必要か? → Yesなら WebSocket 一択
・クライアントが公開エンドポイントを持てるか? → Yesなら Webhook(最もサーバー効率が高い)
・リアルタイム性(秒以内)が必要か? → Yesなら SSE またはロングポーリング
・遅延が許容できるか? → Yesなら ポーリング(実装コスト最小)

「外部サービスとの連携ならWebhook」「ブラウザへのリアルタイム表示ならSSE」「ゲームや株価ならWebSocket」とざっくり覚えておくだけでも、設計の場でのコミュニケーションがスムーズになります。

よくあるハマりポイントと対処法

1. Webhookの冪等性を忘れる

Webhook送信側は「タイムアウトした=失敗」と判断して再送するため、クライアント側が冪等処理を実装しないと同じイベントが2回以上処理されます。order_idなどの一意キーで「処理済みか否か」をチェックするロジックが必須です。

2. WebSocketのスケーリング設計漏れ

オートスケーリング環境では、スケールアウト後の新しいインスタンスに既存の接続が引き継がれません。Redis Pub/Subや Amazon ElastiCacheを使ってインスタンス間でメッセージをブロードキャストする設計が事前に必要です。

3. ロングポーリングとALBタイムアウトの競合

ALBのアイドルタイムアウト(デフォルト60秒)より長い待機時間を設定すると、ALBが接続を切断してしまいます。ロングポーリングのタイムアウト値は「ALBのアイドルタイムアウト-5秒」以内に設定するのが基本です。

4. SSEとHTTP/1.1の接続数制限

ブラウザのHTTP/1.1は同一オリジンへの同時接続数が6つに制限されています。複数SSEを同じドメインで使う場合はHTTP/2対応が前提となります。CloudFrontやALBでHTTP/2を有効化することで解消できます。

Webhook・ポーリング・WebSocket・SSEの違いとは?クラウドAPI連携でリアルタイム通信を設計する実践ガイド - まとめ

本記事のまとめ

・ポーリング: 実装がシンプルだが無駄リクエストが多い。リアルタイム性が不要な場合に限定して使う
・ロングポーリング: ポーリング改良版。WebSocketが使えない環境でのリアルタイム通知に有効
・Webhook: イベント駆動で最もサーバー効率が高い。外部サービス連携の定番。受信側に公開エンドポイントが必要
・WebSocket: 双方向リアルタイム通信が必要な場合の最有力候補。スケーリング設計に注意
・SSE: サーバー→クライアントの一方向で十分な場合、WebSocketより実装がシンプル

クラウドAPI設計全般についてはREST API vs GraphQL vs gRPCの比較ガイドも合わせてご覧ください。

PR

AWSクラウドネイティブデザインパターン(技術評論社)

Webhook・イベント駆動・非同期処理といった通信パターンをAWS上でどう実装するかを、設計パターンの視点から体系的に解説した一冊。本記事で紹介した各パターンの実践的な適用シナリオをさらに深掘りするのに最適です。

関連記事をもっと読む

同じテーマの記事をまとめています。あわせて読みたい記事はこちらからご覧いただけます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次