Push is timely, but it depends on a live connection
Aliases: server push · WebSocket · server-sent events · long-lived connection
What it is
Push lets the server deliver an update when the fact happens, without waiting for the client’s next ask. Freshness can fall to event delay plus network, not to half a polling interval. It depends on a live connection: timely while the socket is alive; once the link goes quiet, is cut by a middlebox, or the process is frozen, push becomes “looks online, already stopped updating”.
Why it happens
The channel (long poll, Server-Sent Events, WebSocket and kin) registers the client as a deliverable endpoint. An event can leave as soon as it exists on the server; the floor on delay is the network, not an asking rhythm. Keeping the channel has its own ledger: heartbeats, NAT timeouts, mobile network handoffs, the OS reclaiming background sockets. Heartbeats too sparse, and a middlebox declares the connection dead; too dense, and battery and traffic return to polling’s waste, only as empty packets.
When the connection drops, the client still shows the last frame from before the drop. If the UI keeps acting as if it is listening, people code silence as “there are no new events”. The product problem of push is often not the connected stretch, but the beat where connected becomes not connected: was that said, and after reconnect is the gap filled. Filling the gap needs a cursor or a version; “just listen for new ones” drops events from the downtime.
Where it stops holding
Firewalls, corporate proxies, and some public networks tear down long-lived connections. Push will fail there forever and must be able to fall back to asking, not only show a connection error. On battery-sensitive phones the OS freezes sockets in the background; foreground “realtime” does not hold after the user switches away. If the receiver cannot keep up (events faster than paint), push becomes a backlog: the UI either drops intermediates or is punched by the stream. That wants coalescing and backpressure, not more realtime. One-way broadcast (a ticker, a headcount) and a two-way session (collaborative carets) demand different connection quality; they should not share one “reconnect until death” policy.
Applying it
- Use push where event density is high and the delay budget is tighter than one asking round: conversation, collaboration, in-flight task state.
- Connection state must be visible: live, reconnecting, offline. While offline, do not keep pretending new events will arrive.
- Reconnect must fill the gap from the pre-drop cursor, not only listen onward. Aim heartbeats at the NAT and background limits of the deployed environment.
- How to check: cut the network on a working push UI. Within a heartbeat timeout, state should become offline or reconnecting, not still claim “live”. After the network returns, events from the downtime must appear, not only events from after recovery. On a network that forbids long-lived connections, fall back to asking rather than spinning.