AlgoMaster Logo

Long Polling vs SSE vs WebSockets

High Priority19 min readUpdated August 14, 2026
Listen to this chapter
Unlock Audio

“The application needs real-time updates” is not enough information to choose a communication mechanism.

A deployment dashboard receives a continuous server-generated log. A chat application sends messages in both directions. A background export only needs to announce completion once. All three can feel real-time to a user, but their traffic shapes are different.

Long polling, Server-Sent Events, and WebSockets can each deliver an update soon after it occurs. The meaningful questions are:

  • Which side sends data, and how frequently?
  • Does the application need text, binary data, or both?
  • How should reconnect, replay, and duplicate handling work?
  • Can every proxy on the path support a long-lived streaming response or protocol upgrade?
  • How many concurrent clients and messages must the system handle?

The best choice is the simplest mechanism that satisfies those requirements reliably.

Three Different Communication Cycles

The three mechanisms differ mainly in what stays open and what must be repeated.

Long polling holds one HTTP request until an event or timeout occurs. The response completes, and the client immediately starts another request.

SSE holds one HTTP response open and writes multiple UTF-8 events into its body.

WebSocket establishes a persistent framed channel on which either endpoint can send messages independently.

These are application communication patterns. Their underlying transport connections can be reused or multiplexed depending on the HTTP version and networking stack.

How Long Polling Works

Long polling extends ordinary HTTP request-response timing. The client sends a request, but the server does not respond immediately when no update is available. It waits until:

  • New data is available
  • The request's maximum wait time expires
  • An error or shutdown requires the request to end

When the response arrives, the client processes it and starts another long poll.

Server holds requestNo event before timeoutGET /events?cursor=142200 OK, event 143GET /events?cursor=143200 OK, empty event listGET /events?cursor=143200 OK, events 144–146ClientServer
8 / 8
algomaster.io

A response could contain JSON:

If no event arrives before the application timeout, the server can return an empty result:

The client immediately starts another request. On network or server errors, it retries with backoff rather than entering a tight failure loop.

Long Polling Is Not Short Polling

With ordinary short polling, the server responds immediately whether or not anything changed:

Update latency depends on the polling interval. A five-second interval can deliver an event almost immediately or nearly five seconds late.

With long polling, a request is already waiting when the event occurs:

This usually provides much lower update latency without sending repeated empty requests at a short interval.

The Timeout Is Intentional

No request should wait forever. Servers, gateways, load balancers, clients, and network address translation devices all impose timeouts.

The application chooses a long-poll timeout below the shortest relevant infrastructure timeout. If a proxy ends idle upstream requests after 30 seconds, an application might complete its poll earlier and let the client renew it.

There is no universal safe timeout. It must be tested through the real production path. A longer timeout reduces empty response churn, while a shorter timeout detects broken paths sooner and is more likely to survive restrictive intermediaries.

Use a Cursor

There is a small interval between receiving a response and establishing the next poll. An event that occurs during this interval must not disappear.

A cursor makes the request describe the client's position:

The server returns events after 143, whether they appeared before or after the new request arrived. This requires retained event state or a way to construct a fresh snapshot.

Without a cursor or server-side queue, long polling can lose events in the gap between requests. Starting multiple overlapping polls may appear to close the gap, but it creates ordering, duplication, connection-consumption, and cancellation problems. One logical outstanding poll per subscription is usually easier to reason about.

A Direct Comparison

The most important differences are summarized below.

DimensionLong PollingServer-Sent EventsWebSocket
Communication directionServer replies to a waiting request; client uses HTTP requestsServer to client; client uses separate HTTP requestsFull-duplex on one channel
Connection patternRepeated held requests and complete responsesOne long-lived HTTP responseOne long-lived framed connection
Browser APIfetch() or another HTTP clientEventSourceWebSocket
PayloadAny HTTP representation, including JSON or binaryUTF-8 text event recordsText or binary messages
Per-update overheadHTTP response plus next requestSmall text field prefixesCompact frame header after handshake
ReconnectionApplication loopAutomatic in EventSourceApplication logic
Resume supportApplication cursorid and Last-Event-ID, plus server replayApplication cursor or acknowledgment
Intermediary concernsRequest timeouts and repeated routingResponse buffering and idle timeoutsUpgrade or extended CONNECT support and idle timeouts
BackpressureOne response naturally gates the next pollContinuous stream needs bounded server queuesContinuous channel needs bounded queues
Typical fitInfrequent updates or restrictive infrastructurePrimarily server-to-client text updatesFrequent bidirectional or binary interaction

The table describes protocol capabilities, not complete delivery guarantees. Authentication, replay storage, authorization, idempotency, and fan-out remain application responsibilities in all three designs.

Loading simulation...

Directionality and Application Shape

Directionality is usually the first decision.

Mostly Server to Client

SSE directly matches feeds where the server produces most of the traffic:

The client can still send commands with ordinary HTTP. For example, a browser might receive order updates through SSE and submit POST /orders separately.

Long polling has the same logical direction for updates but closes the response after each delivery or timeout. It is useful when the environment handles complete HTTP responses more reliably than partial streaming responses.

Frequent Traffic in Both Directions

WebSocket is designed for both endpoints to send whenever needed. It avoids modeling each client message as a separate HTTP request and each server message as a response or stream event.

This fits interactions such as:

A bidirectional product does not automatically require WebSocket. A chat with infrequent client messages could use HTTP POST for sending and SSE for receiving. WebSocket becomes more compelling when both directions are frequent, latency-sensitive, or part of one shared session.

Latency and Message Overhead

All three can deliver a server event quickly while their connection or request is active.

SSE and WebSocket keep a continuous delivery path. Long polling has a waiting request most of the time, so its steady-state event latency can also be close to one network transit. Its extra latency appears during the brief renewal gap after each response and during retries.

Their overhead differs more as message frequency rises.

Long polling repeats HTTP processing for every response and replacement request. Headers may include cookies, tracing data, routing information, and authentication. HTTP/2 header compression and persistent transport reuse reduce wire cost, but the application, gateway, and server still process repeated request lifecycles.

SSE pays the HTTP setup once per connection and uses text field prefixes for each event:

WebSocket pays an opening handshake and then uses compact frames. This is valuable for many small messages, although masking, TLS records, application envelopes, and network packets mean the real cost is more than the minimum frame header alone.

For sparse updates, these byte differences are rarely the most important factor. Compatibility, reconnect behavior, and implementation simplicity usually matter more. At high message rates, repeated long-poll request processing becomes increasingly expensive.

A Capacity Example

Suppose 100,000 connected clients have no updates and renew a long poll every 25 seconds. If renewals are evenly spread, timeout alone completes and replaces roughly:

The server also holds close to 100,000 requests concurrently.

If every client receives one update per second and each response carries one event, the design can approach 100,000 completed responses and replacement requests per second. Batching can reduce that churn, but it can increase latency.

SSE and WebSocket still require roughly 100,000 live client streams or channels and must deliver the same 100,000 updates per second. They avoid renewing an HTTP request for every update, but they do not eliminate the fan-out work or concurrent connection state.

Connection and Server Resource Costs

Long polling is sometimes described as avoiding persistent connections. That is misleading.

While waiting, every client has an outstanding request and occupies a transport stream or connection, server request state, a timeout, and often subscription state. Long polling reduces unnecessary responses compared with short polling; it does not remove concurrent waiters.

SSE and WebSocket also keep state for each connected client. Their connection lifetime is more explicit, and a single connection can deliver many messages without repeatedly rebuilding request context.

At scale, none of the three should reserve a blocked operating-system thread for every idle client. The server needs an I/O model that can hold many waiting requests or connections efficiently. The exact concurrency implementation belongs to the server platform, but the capacity question is shared by all three approaches.

HTTP/2 and HTTP/3 multiplexing can let many long polls or SSE streams share fewer underlying connections. WebSocket can also use modern HTTP bootstrapping when the client, server, and intermediaries support it. Multiplexing reduces transport-connection contention; it does not eliminate per-subscription memory and processing.

Intermediaries and Deployment Environments

Real traffic often passes through a CDN, web application firewall, API gateway, reverse proxy, and load balancer before reaching an application.

Long Polling

Long polling uses complete HTTP responses. This makes it broadly compatible with HTTP-aware infrastructure, but every intermediary must permit the request to remain pending long enough. Cache behavior must be disabled, and gateway timeouts must be coordinated with the application timeout.

Because each response completes, every new request can be routed to a different application instance. This works well when instances share the event store and the cursor contains enough resume state.

SSE

SSE is ordinary HTTP, but intermediaries must forward partial response data promptly. Proxy buffering, response compression, caching, and idle timeouts can turn immediate events into delayed batches or terminate the stream.

The connection stays attached to the serving gateway or application process for its lifetime. After reconnecting, it can land on another instance and resume using the last event ID if shared replay state exists.

WebSocket

A classic WebSocket connection requires support for the HTTP upgrade and then for long-lived bidirectional traffic. HTTP/2 and HTTP/3 use extended connection mechanisms rather than the classic 101 transition, so support must be verified end to end.

After establishment, the connection stays attached to the gateway and process that own it. Proxies need suitable idle timeouts and must forward Close, Ping, Pong, text, and binary frames correctly.

Modern infrastructure commonly supports all three, but configuration defaults still matter. A successful local test against the application server does not prove that the production path will behave the same way.

Reconnection, Ordering, and Delivery Guarantees

Network connections fail. Mobile devices change networks, laptops sleep, proxies expire idle state, and deployments restart servers. The selection should include the recovery design, not only the healthy connection.

Long Polling Recovery

The application owns the request loop. After a timeout, it polls again immediately. After an error, it normally uses exponential backoff with jitter.

A cursor tells the next server where to resume. Keeping only one logical poll in flight helps preserve ordering; overlapping requests can return in a different order from the events they represent.

SSE Recovery

Browser EventSource reconnects automatically. An SSE id becomes the Last-Event-ID request header, which gives the server a standard cursor mechanism.

This is convenient but not sufficient by itself. The server still needs replay storage, retention rules, and behavior for an expired cursor.

WebSocket Recovery

The browser WebSocket API does not reconnect automatically. The application creates a new connection, reauthenticates, restores subscriptions, and sends a cursor or requests a fresh snapshot.

If the application needs confirmation that a command was processed, it defines acknowledgment messages and idempotency keys.

None Provides Exactly Once

In all three cases, a connection can fail at an ambiguous moment:

The sender may not know whether the consumer processed it. Replay can prevent gaps but introduce duplicates. Preventing both loss and duplicate effects requires application-level IDs, durable state, acknowledgments where appropriate, and idempotent handling.

Ordering also has a boundary. SSE and WebSocket preserve event or message order within one live stream. Long polling can preserve order with a single request and cursor. After reconnecting, ordering depends on the server's replay or snapshot logic.

Backpressure and Slow Clients

Backpressure asks what happens when updates are produced faster than one client can consume them.

Long polling provides a degree of natural pacing when the client starts the next request only after processing the previous response. The server may batch events after the cursor. However, the retained backlog can still grow, and a large response can overwhelm a slow client.

SSE continuously writes events into one response. Browser EventSource exposes no application-controlled flow signal, so the server needs bounded queues and a policy to combine updates, drop replaceable data, or disconnect slow clients for later resume.

WebSocket libraries also need queue limits. The stable browser API exposes bufferedAmount for outbound bytes but does not automatically solve inbound application backpressure.

The correct policy depends on event meaning:

  • A progress percentage can replace an older percentage.
  • A live metric can often drop stale samples.
  • A financial transaction or audit record may require durable replay.
  • A multiplayer position update may become useless once a newer state exists.

Protocol choice does not decide which data is safe to drop.

Browser Authentication and Security

All three should use encrypted transport in production: HTTPS for long polling and SSE, and wss for WebSocket.

Long polling implemented with fetch() has the normal HTTP request surface. It can use cookies, an Authorization header, custom headers, and ordinary CORS rules.

Browser EventSource uses GET, supports cookies according to its credentials mode, and can enable cross-origin credentials with withCredentials. It does not expose a general way to add arbitrary authorization headers or a request body.

The browser WebSocket constructor similarly does not accept arbitrary HTTP headers. A WebSocket server can authenticate cookies during the handshake or authenticate through application messages after opening. It must validate the browser's Origin because WebSocket is not governed by ordinary CORS response processing.

Regardless of transport:

  • Authenticate the connection or request.
  • Authorize every subscription and command.
  • Validate message sizes and schemas.
  • Rate-limit reconnects and abusive traffic.
  • Treat cursors and event IDs as untrusted input.
  • Avoid placing long-lived secrets in URLs that may be logged.

The transport changes how credentials arrive, not whether access control is required.

Scaling and Graceful Deployment

All three mechanisms need a way to route a published event to interested clients.

With long polling, waiting requests may be distributed across many servers. A shared event log, database, or notification layer wakes the correct waiters. A cursor lets a replacement request reach a different server safely.

With SSE and WebSocket, a connection registry maps subscribers to the server processes or gateways that own their live connections. A shared publish-subscribe layer distributes each update to those owners.

During deployment:

  • Long polls can return early and let clients issue fresh requests.
  • SSE servers can end responses; EventSource reconnects.
  • WebSocket servers can send a going-away Close frame and let application reconnect logic run.

Reconnects should be spread with jitter or controlled retry delays. Releasing a large fleet of clients simultaneously creates a reconnect storm that can overload authentication, load balancers, and the new application instances before normal traffic resumes.

Operational metrics should distinguish:

HTTP request rate alone badly underrepresents SSE and WebSocket load, while connection count alone hides long-poll churn.

Choosing for Common Workloads

Background Job Completion

A client starts a job and waits for one result. Long polling is often sufficient: hold the request until the job completes or the poll times out, then retry with the job ID.

If one page tracks many jobs and receives frequent progress updates, one SSE stream can consolidate them more efficiently.

Notification Feed

Notifications primarily flow from the server and are naturally represented as text records. SSE provides named events, automatic reconnect, and event IDs. Long polling remains a reasonable fallback where streaming responses are buffered or unsupported.

Live Dashboard or Deployment Logs

The server continuously emits metrics, status changes, or log lines. SSE closely matches the direction and can use normal HTTP infrastructure. Replay cursors help a dashboard recover after a brief network change.

Chat

Chat can be built with client POST requests and SSE delivery. That design is attractive when messages from the client are relatively infrequent and ordinary HTTP command semantics are useful.

When the experience includes frequent messages in both directions, typing state, presence, read receipts, and interactive session state, WebSocket usually provides a cleaner single-channel model.

Multiplayer Interaction or Collaborative Editing

Both endpoints send frequent, latency-sensitive operations. WebSocket is usually the natural choice because it provides a persistent full-duplex channel with low per-message framing overhead.

Restrictive or Unknown Networks

When compatibility with conservative HTTP infrastructure is the dominant requirement, long polling is often the safest starting point because it uses complete HTTP responses. Its timeout and load costs still need to be measured.

A Practical Decision Process

This flow is a starting point, not a substitute for testing. Prototype through the actual CDN, gateway, load balancer, authentication layer, and client networks. Measure delivery latency, resource use, reconnect behavior, and slow-client handling under realistic concurrency.

Common Misunderstandings

Long polling is not frequent short polling. The server holds the request until an event or timeout rather than immediately returning an empty response.

Long polling does not eliminate concurrent connections or requests. Each waiting client still consumes server and transport state.

A long poll does not require a new TCP handshake every time. HTTP can reuse or multiplex the underlying connection even though each response and request is a distinct HTTP exchange.

SSE is not automatically slower than WebSocket. Both can deliver an event promptly over an established path; workload and buffering determine observed latency.

WebSocket is not always more scalable. It reduces repeated request framing, but every live connection still consumes memory, routing state, and fan-out work.

SSE is not limited to one browser event name. Its event field supports named event types.

SSE cannot carry native binary messages. Encoding binary as text adds size and processing cost.

Full-duplex is not useful when only one side has something to say. Extra capability can introduce unnecessary connection and application complexity.

Automatic reconnection is not reliable replay. SSE reconnects automatically, but the server must retain events and interpret Last-Event-ID.

Persistent delivery does not mean exactly-once delivery. Every option needs explicit gap, duplicate, and ambiguous-failure handling.

Infrastructure support cannot be assumed from a local test. Timeouts, buffering, upgrades, and connection limits appear along the complete production path.

Protocol selection does not replace message design. IDs, versions, schemas, authorization, and error semantics remain application concerns.

Summary

Long polling, SSE, and WebSocket support low-latency updates with different communication models. Long polling returns one HTTP response per event or timeout, fitting infrequent updates and restrictive infrastructure. SSE keeps one response open for server-to-client text events with browser-managed reconnection and event IDs. WebSocket provides a full-duplex framed channel for frequent bidirectional or binary messages.

Long polling repeats request processing, while SSE and WebSocket retain connection state. None guarantees replay, deduplication, or exactly-once effects without application support. Production choices must also account for buffering, timeouts, backpressure, security, client count, and reconnect storms.

Choose long polling for compatibility, SSE for one-way text streams, and WebSocket only when a true two-way channel is needed.

Quiz

Long Polling vs SSE vs WebSockets Quiz

5 quizzes