Real-Time Systems

WebSockets vs Polling for Real-Time Services

When polling is enough, when WebSockets earn their operational cost, connection management at scale, and hybrid patterns for live maps, offers, and status fan-out.

SystoBase Engineering · · 14 min

Key takeaways

  • Polling is underrated for early scale — simpler ops, easier caching, sufficient for many UX paths.
  • WebSockets shine for high-frequency fan-out (live location, live status) with many concurrent subscribers.
  • Industry pattern: WebSockets everywhere day one; SystoBase recommendation: poll until measured pain, then targeted upgrade.
  • Connection state is infrastructure — heartbeats, reconnect storms, auth refresh.
  • Redis pub/sub or streams bridge hot ingestion to socket nodes.
  • Always authorize subscription by resource ID — no global firehose.

Product requirements first

Real-time is not binary — a user waiting for acceptance may tolerate a 2–3s poll interval; a user watching a live map wants sub-second updates. Define latency budgets per screen before choosing WebSockets. Live ops dashboards, logistics tracking, marketplace status, and mobility apps all face the same transport choice.

Time-sensitive offers may need push notification plus an in-app modal — transport to the device is FCM/APNs as much as WebSocket.

Industry pattern: uniform real-time stack. SystoBase recommendation: per-feature transport choice documented in an ADR with expected concurrent connections.

Polling patterns that work

ETag or version-based polling: client sends If-None-Match, server returns 304 when domain state is unchanged — cuts payload on waiting screens.

Adaptive interval: back off when idle, tighten near expected state-change windows after assignment.

Polling scales horizontally with a stateless API and Redis cache of the resource snapshot — no sticky sessions required.

Where WebSockets win

Live location on a map at 1–2 updates/sec justifies a persistent connection — polling at that rate wastes battery and bandwidth. Courier tracking and fleet maps are common cases; the service pattern is the same.

Operator war rooms watching many active jobs — multiplex channels with authorization per resource.

Industry pattern: single global socket per app. SystoBase recommendation: namespaced channels (/jobs/{id} or /orders/{id}) with subscribe auth validating the caller’s role.

Connection management

Heartbeats detect dead connections; server-side sweeps clear stale sessions. Mobile backgrounding drops connections — clients must resync state on resume.

Reconnect storms after deploy: jitter backoff, rate-limit socket accepts at the load balancer, readiness probes before cutting old pods.

Auth tokens expire — refresh without dropping the channel, or re-subscribe with a new token seamlessly.

Hybrid architecture

Common pattern: poll status until accepted, then upgrade to WebSocket for the live-tracking phase only — reduces concurrent socket count during peak waiting.

Location pipeline: mobile → ingestion → Redis GEO → pub/sub to socket fleet → client. Keep PostgreSQL off the hot read path for map pins.

Industry pattern: socket server hits the DB every message. SystoBase recommendation: push deltas from cache with sequence numbers for client ordering.

Failure modes

Sticky session misconfiguration routes a client to a node without their channel — ghost disconnects. Prefer Redis-backed pub/sub fan-out with stateless socket nodes.

Memory leaks in connection handlers take out nodes silently — monitor open fds and heap per instance.

Fallback to polling when the socket fails — the product must degrade gracefully, not blank the UI.

Decision rubric

Choose polling if: update frequency < 0.5 Hz, few concurrent subscribers per resource, team lacks socket ops experience, MVP timeline is tight.

Choose WebSockets if: live map tracking UX, many simultaneous field updates, bi-directional low latency needed, measured poll load exceeds socket ops cost.

Revisit the decision at 10× concurrency — polling cost rises linearly; sockets cost rises with connections but save bandwidth.

Sources

  1. RFC 6455 WebSocket Protocol
  2. Redis Pub/Sub