Konrad Kowalski (rootsher)Principal Platform & Reliability Architect000001000011110011101000111110101001100110100101

Realtime in the Browser: From Polling to WebTransport

date
category
Backend
also in
Frontend · Networking
reading
2 min / 353 words

The classic model of the web is simple:

text
client -> request -> server
client <- response <- server

The client starts the communication. The server answers.

The problem begins when state changes on the backend after the request has finished.

text
t=0   GET /orders/42 -> processing
t=4   backend: processing -> completed

How is the frontend supposed to learn about the change at t=4?

That is the starting point of this series.

We will not treat "realtime" as a single technology. Realtime is a requirement about the maximum acceptable delay of information, not the name of a protocol.

text
realtime != WebSocket

For one system an update after 10 seconds is fast enough. For another 100 ms is too slow.

We will go through the mechanisms from the simplest to the most flexible:

text
Polling
  |
  v
Long Polling
  |
  v
HTTP Streaming
  |
  v
Server-Sent Events
  |
  v
WebSocket
  |
  v
WebTransport

Each of them follows from a specific limitation of the previous one.

Polling repeats requests even when nothing has changed. Long polling lets the server delay the response. HTTP streaming lets a single response carry many chunks of data. SSE adds a standard event format and reconnection to such a stream. WebSocket leaves the request/response model behind and gives a persistent full-duplex channel. WebTransport goes further: many independent streams plus datagrams over HTTP/3.

Along the way we will also separate layers that often get mixed up:

text
WebSocket
-> protocol + browser API

Socket.IO
-> higher-level realtime protocol/framework

GraphQL Subscription
-> application-level subscription semantics

WebRTC DataChannel
-> peer-to-peer communication

Socket.IO can use WebSocket, but Socket.IO is not WebSocket.

A GraphQL subscription can be delivered over WebSocket or another transport, but the subscription itself does not define the transport.

WebRTC solves yet another problem, because once the connection is established the data can flow peer to peer instead of frontend ↔ backend.

The series focuses on client to server communication. It is not a tutorial for building a chat, nor a catalogue of libraries.

What matters here are the mechanisms:

  • who initiates the flow of data,
  • how long a request or a connection lives,
  • where the connection state exists,
  • what the data framing looks like,
  • what happens on reconnect,
  • how the mechanism affects the load balancer and the backend,
  • where backpressure shows up,
  • what "push" really means.

In the end the choice of technology should follow from the traffic model:

text
How fresh must data be?
  |
  v
Who sends data?
  |
  v
How often?
  |
  v
Do messages need ordering?
  |
  v
Can old messages be discarded?
  |
  v
What connection state can infrastructure support?

Only then do we pick a mechanism.

Not the other way round.