Skip to content

Real-Time Protocols: WebSockets, Server-Sent Events (SSE), and Long Polling

What it is

Real-time protocols maintain a server-to-client event path so a client receives updates without repeatedly asking whether data exists. WebSockets support bidirectional messaging over one upgraded connection, Server-Sent Events (SSE) stream one-way events over HTTP, and long polling has the server hold each HTTP request open while waiting for an event or timeout.

How it works

A transport selection determines the connection model, message direction, failure behavior, and server resource cost. The three mechanisms expose different choices rather than different guarantees for the same application event:

    sequenceDiagram
    participant Client
    participant Gateway
    participant Broker
    alt WebSocket
        Client->>Gateway: Upgrade HTTP connection
        Gateway-->>Client: 101 Switching Protocols
        Gateway->>Broker: Subscribe to client topics
        Broker-->>Gateway: Matching application event
        Gateway-->>Client: Event on the duplex connection
    else Server-Sent Events
        Client->>Gateway: GET event feed
        Gateway-->>Client: 200 text/event-stream
        Gateway->>Broker: Subscribe to client topics
        Broker-->>Gateway: Matching application event
        Gateway-->>Client: Event with id and data
    else Long polling
        Client->>Gateway: Open ordinary request
        Gateway->>Broker: Subscribe to client topics
        Broker-->>Gateway: Matching application event
        Note over Client,Gateway: Gateway holds the request until an event or deadline
        Gateway-->>Client: Event or empty timeout response
    end
    Client->>Gateway: Reconnect with resume token
  
websocket:
  establishment: HTTP upgrade to a full-duplex connection
  direction: client-to-server and server-to-client
  framing: text or binary frames over TCP
  reconnect: application and client policy
sse:
  establishment: long-lived HTTP response
  direction: server-to-client
  encoding: text/event-stream
  reconnect: EventSource with Last-Event-ID support
long_poll:
  establishment: ordinary HTTP request
  direction: request-response with server-side waiting
  reconnect: immediate next request after each response

WebSockets begin with an HTTP/1.1 upgrade request containing Connection: Upgrade, Upgrade: websocket, and Sec-WebSocket-Key. After the server accepts the handshake, the connection carries WebSocket frames rather than a sequence of HTTP requests. Control frames handle close and ping/pong, while application heartbeats and sequence numbers detect a stale or interrupted session. WebSocket preserves the ordered TCP byte stream, but it does not define event replay, durable delivery, or automatic reconnection.

Server-Sent Events return an HTTP response with Content-Type: text/event-stream. The server writes id, event, and data fields, and a browser’s EventSource reconnects when the stream ends. After a supported reconnection, the client sends the last received event ID in Last-Event-ID; the server can use that identifier to resume. Client-to-server events use separate HTTP requests because the SSE response is one-way. Token refresh, connection limits, proxy buffering, and response lifetime still require explicit configuration.

Long polling sends an ordinary request that identifies the client’s last event or wait deadline. The server holds the request until a matching event arrives or its own timeout expires, then responds. The client sends another request immediately. This works through intermediaries that support ordinary HTTP but block streaming responses or connection upgrades, at the cost of repeated requests and connection churn across successive waits.

Server push and server pull describe who initiates delivery. A WebSocket or SSE server pushes an event over an already-established stream, while fixed-interval polling makes the client pull by issuing a new request. Long polling is a hybrid: the client initiates each HTTP request, but the server waits and returns as soon as an event is available. None of these transport choices guarantees replay; a resume token, durable event store, or broker offset must supply missed-event recovery.

A scalable service normally separates connection handling from message routing. Stateless or mostly stateless gateways authenticate sessions and publish events to a shared broker; gateway nodes subscribe for the users connected to them. This removes a mandatory need for sticky sessions, although local routing state, device updates, or non-replayable requests can still benefit from affinity. Shared subscription placement, heartbeats, backpressure, and replay are the actual scaling concerns.

Tradeoffs

ProtocolGainCost or limitation
WebSocketsFull-duplex interaction with one upgraded connection and compact message framingApplication owns heartbeat, replay, resumption, and proxy behavior; one server socket per connection
SSEHTTP-native server push, event IDs, and browser-managed reconnectionOne-way stream; browser and proxy connection limits still apply
Long pollingBroad HTTP compatibility; the server holds the request open until an event or timeoutRepeated requests, extra handshakes, and more load than a persistent stream
Broker-backed fan-outGateways remain horizontally scalable and independent of event originBroker ordering, backpressure, and availability affect every connected gateway
Connection affinityKeeps local state on one gateway and can avoid a broker readA failed node disconnects its clients and reduces routing flexibility
Stateless gatewaysClients reconnect to any healthy gateway after externalized stateSession restoration and fan-out require shared state or a broker

When to use

  • You need client-to-server and server-to-client messages over one connection, which points to WebSockets.
  • You need a browser to consume a one-way event feed with standard HTTP and event-ID resumption, which points to SSE.
  • You need server push through restrictive proxies or clients without upgraded or streaming responses, which points to long polling.
  • You operate long-lived sessions and need to budget sockets, gateway capacity, heartbeats, and reconnection behavior.

Alternatives

  • Fixed-interval HTTP polling — uses simple cacheable requests, but adds idle traffic and latency bounded by the polling interval.
  • WebTransport — multiplexes unreliable and reliable streams over HTTP/3, but requires newer clients, servers, and network support.
  • WebRTC data channels — support peer-to-peer or relayed bidirectional data after signaling and NAT traversal, but add substantially more connection setup.
  • MQTT — fits constrained devices and brokered publish/subscribe clients, but requires a broker model different from browser-native HTTP streaming.

Related