← Docs

Recipe: Long-polling design & tradeoffs

When WebSockets are blocked or impractical, long-polling keeps clients in sync with minimal infrastructure.

Core loop

Client                          Server
  |                                |
  |--- GET /poll?since=ts -------->|
  |                                |-- wait for event or timeout
  |<-- 200 { events[] } ----------|
  |                                |
  |--- GET /poll?since=new_ts --->|

The client holds an open HTTP connection. The server blocks until data is available or a configurable timeout expires, then responds. The client immediately reconnects.

Tradeoffs

  • Latency — bounded by poll interval + network RTT. Acceptable for dashboards and license-sync flows.
  • Connection churn — every cycle tears down and rebuilds TCP/TLS. HTTP/2 multiplexing mitigates this.
  • Server cost — blocked threads or async tasks per client. Use an event bus (Redis pub/sub, in-memory channel) to unblock efficiently.
  • Ordering — a monotonic cursor (timestamp or sequence number) prevents gaps. Store the cursor client-side.

When to use

Prefer long-polling when you control both client and server, need real-time updates, and cannot deploy WebSocket infrastructure. Meridian uses it for license-status push and config hot-reload behind restrictive corporate firewalls.