Skip to content

BlogEngineering Resources

WebSockets vs. Polling vs. SSE: What Actually Costs More

WebSockets vs. Polling vs. SSE: What Actually Costs More

At the protocol-framing level, WebSockets have a clear advantage over fixed-interval short polling. A WebSocket frame has 2 to 14 bytes of framing overhead under RFC 6455, depending on payload length and masking. A polling exchange carries HTTP request and response metadata and incurs a round trip even when nothing has changed. Its exact wire cost depends on the HTTP version, header compression, connection reuse, TLS, cookies, and authentication.

That is not enough to size or price a system. Per-message overhead omits the capacity consumed by idle open connections. For a large, mostly idle client population, persistent-connection capacity can make WebSockets more expensive overall, but only local measurements can establish that result.

The per-message trap

If clients exchange messages constantly, the connection setup and persistent state are amortized across substantial traffic. Chat, multiplayer games, collaborative editing, and live trading views are natural WebSocket workloads because they often require frequent, bidirectional communication.

The trade-off changes when each client receives updates infrequently. A dashboard that updates a few times an hour, a notification badge, or an order-status page that changes twice during a delivery may spend most of its life idle. A WebSocket still occupies capacity throughout that idle period.

What an idle connection costs

A WebSocket consumes state at several boundaries: the terminating process may hold a socket object, protocol and application state, and buffers; the host kernel owns the file descriptor and socket buffers; and a load balancer, proxy, or edge service may hold more state. These allocations do not all reside in the gateway process, and their size depends on the stack and workload.

Heartbeats add CPU and network work when used to detect stale connections. Measure per-connection memory and safe connection limits on the chosen stack under representative traffic, slow-client behavior, and latency thresholds. A raised file descriptor limit is a ceiling, not tested serving capacity.

A resource model, not a price result

The provisional numerical inputs show the accounting. Replace them with load tests, wire measurements, capacity limits, redundancy requirements, headroom, and unit prices from the architecture being evaluated.

Use one boundary for both alternatives: 100,000 browser clients connect through the same regional edge and load balancer. Fixed-interval short polls terminate on stateless HTTP workers; WebSockets terminate on a connection gateway. Both paths use the same authentication and downstream data source.

Hold the application contract equal across fixed-interval polling, long polling, SSE, and WebSockets. Decide whether clients need only the latest state or every event, then apply the same requirements for ordering, duplicate handling, retention, replay or catch-up, and recovery after disconnection. Neither SSE nor WebSockets supplies application-level history and recovery by itself. Include the resulting storage, routing, and recovery work in the comparison.

Suppose each client receives one update per hour and the product requires delivery within 30 seconds. A 30-second polling interval produces:

100,000 / 30 ≈ 3,333 requests per second

That rate follows from client count and the latency-driven interval, not message frequency. A 30-second interval has a worst-case detection delay near 30 seconds before network and processing, so margin may require a shorter interval. One update per client per hour is a population mean of about 28 delivered updates per second, assuming independent arrivals spread across the hour. A correlated event sent to all 100,000 clients creates a burst, so representative capacity tests must include expected fan-out correlation and burst shape. Update frequency affects payload traffic and batching, but not the fixed-interval base polling rate.

To compare the alternatives in common monetary units, define:

  • N as client count; T as the polling interval; and λ as updates per client per second.
  • b0 and c0 as baseline wire bytes and CPU time incurred by every poll, excluding delivered-update work. dp and cp are the incremental bytes and CPU time per update delivered through polling; dw and cw are the corresponding WebSocket terms.
  • mhttp as per-client retained HTTP state, if connections are reused, and mws as per-client persistent WebSocket state aggregated across the gateway, kernel, edge, and other boundaries being measured.
  • H, bh, and ch as heartbeat interval, wire bytes, and CPU time per heartbeat cycle.
  • rh and rw as HTTP and WebSocket connection establishments per client per second. ehb and ehc are HTTP establishment bytes and CPU; ewb and ewc cover WebSocket handshake and TLS work, authentication, subscription setup, and any reconnect or resumption work.
  • Pcpu, Pbyte, and Pmem as prices per CPU-second, transferred byte, and byte-hour. Qpoll is a per-poll provider charge, Qh and Qw are per-establishment charges, and Qconn is a WebSocket connection-hour charge. Fpoll and Fws cover fixed hourly fleet or edge charges.

An hourly per-client model can then be written as:

Cpoll / N = 3600[((c0 / T + λcp + rh·ehc)Pcpu) + ((b0 / T + λdp + rh·ehb)Pbyte) + Qpoll / T + rh·Qh] + mhttpPmem + Fpoll / N

Cws / N = 3600[((ch / H + λcw + rw·ewc)Pcpu) + ((bh / H + λdw + rw·ewb)Pbyte) + rw·Qw] + mwsPmem + Qconn + Fws / N

Authentication performed on every poll belongs in c0; connection-specific authentication belongs in the relevant establishment term. Set the expressions equal only after measuring the variables. Tiered prices should be modeled piecewise rather than hidden in a fixed charge. The result is a break-even for the defined workload, service contract, and billing boundary, not an inference from unmatched figures such as network throughput and resident memory.

Capacity constraints still apply outside the equation. Polling workers must sustain the measured request rate while meeting CPU and latency thresholds. The gateway fleet must keep connection count, file descriptors, memory, heartbeat work, and slow-client buffers within tested limits. Fleet sizing must include the chosen redundancy model and headroom; standby capacity and failover behavior need representative load tests rather than a simple multiplier.

Without fixed or nonlinear terms, both totals scale with client count, leaving the variable per-client crossover unchanged. With the fixed terms, totals are affine: changing N changes Fpoll / N relative to Fws / N when fixed costs differ. Per-request and per-connection charges scale with their drivers, while tiered pricing, fleet rounding, and edge limits can change the slope or add steps. Message frequency changes delivered payload and batching: polling can return several accumulated updates in one response, while WebSockets can send each update separately or batch them. At high frequency, framing, latency, and bidirectional traffic may favor WebSockets, depending on the measured terms.

This example is specifically about fixed-interval short polling. Long polling reduces empty responses by holding a request until data arrives or a timeout expires, but retains connection and intermediary state. Reused HTTP/2 or HTTP/3 connections and header compression can reduce polling overhead while preserving transport state. Full accounting must include HTTP framing, TLS and transport overhead, relevant retransmissions, and connection state charged at the edge or load balancer.

The options can also be combined: WebSockets for an active cohort, polling for a long idle tail, or a downgrade path where quiet connections close and clients resume polling.

SSE is a one-way push option

When updates flow only from server to client, Server-Sent Events can provide a simpler semantic and browser API than WebSockets. The browser EventSource interface automatically reconnects, and the HTML standard defines how a client sends Last-Event-ID when reestablishing the stream (WHATWG HTML). That transport behavior does not provide event retention or guarantee replay. The application still owns authorization, event history, replay rules, and recovery when the requested history is no longer available.

SSE is not an escape from persistent-connection cost. It retains long-lived connections, memory, file descriptors, and intermediary state, and deployments may require proxy-buffering and timeout configuration. Its advantage is the one-way event-stream model. For occasional upstream actions, SSE can be paired with regular HTTP requests; frequent bidirectional traffic is a stronger reason to evaluate WebSockets.

The operational bill for WebSockets

If the workload justifies WebSockets, plan for what they change operationally:

  • Capacity planning. Track concurrent connections, traffic, memory, file descriptors, heartbeat work, and buffered bytes. Derive safe connections per instance from load tests at the required latency and resource thresholds, not from configured maxima.
  • Connection ownership and event routing. Load balancers need suitable upgrade support, timeouts, and draining behavior. Affinity is required only when routing depends on node-local connection or session state. Shared state or external pub/sub can route events without conventional sticky sessions, at the cost of another dependency and delivery path.
  • Backpressure. Slow clients can accumulate buffered data. Set per-connection limits and define whether to drop data, coalesce updates, or disconnect the client before shared process resources are exhausted.
  • Reconnects and authentication. Reauthentication behavior depends on token lifetime and security policy; some systems validate during the connection, while others validate on reconnect. Gateway failures can synchronize WebSocket reconnects, but polling retries and SSE reconnects can also create herds. Apply randomized jitter and capped exponential backoff to all three, while preserving the product's recovery target.

Companion articles on the per-message and per-connection cost model (August 11) and persistent-connection fan-out (August 13) are forthcoming.

A concise interview answer is: “WebSockets minimize framing overhead per message, but long-lived connections continuously consume capacity, so for a large, mostly idle client population I would measure fixed-interval polling, long polling, SSE, and WebSockets against the same latency and delivery contract rather than assume push is cheaper. I would choose based on directionality, update and payload frequency, batching, service semantics, tested connection and request capacity, and measured operating cost.”

Share this post