Home/Learn/Computer Networks/Long Polling vs SSE vs WebSocket

Long Polling vs SSE vs WebSocket

Intermediate
Interview Patterns

Three patterns for pushing real-time data from server to client — long polling (HTTP hack), Server-Sent Events (one-way HTTP stream), and WebSocket (full-duplex TCP channel) — each with distinct trade-offs in complexity, scalability, and browser support.

Overview

HTTP is request-response by design — clients ask, servers answer. But many applications need servers to push data (notifications, live feeds, chat, collaborative editing). Three techniques exist: Long Polling holds the HTTP request open until data arrives, then the client immediately re-requests. Server-Sent Events (SSE) is a persistent one-way HTTP stream for server→client pushes. WebSocket upgrades the HTTP connection to a full-duplex TCP channel for bidirectional real-time communication. Choosing the right pattern depends on the directionality, latency requirements, infrastructure constraints, and whether load balancers support the protocol.

Long Polling

Long polling is a workaround for HTTP's request-response model. The client sends a request and the server holds it open — responding only when data is available (or a timeout occurs). The client immediately sends the next request. This creates a pseudo-push mechanism with standard HTTP.

Long polling implementation
// Long polling — client side (JavaScript):
async function longPoll() {
  while (true) {
    try {
      const res = await fetch('/api/notifications?lastId=' + lastEventId, {
        signal: AbortSignal.timeout(30000)  // 30s server timeout
      })
      const data = await res.json()
      if (data.events?.length) {
        processEvents(data.events)
        lastEventId = data.events.at(-1).id
      }
      // Immediately reconnect
    } catch (e) {
      await sleep(1000)  // backoff on error
    }
  }
}

// Server side (Spring Boot):
@GetMapping("/api/notifications")
public DeferredResult<List<Event>> poll(@RequestParam Long lastId) {
  DeferredResult<List<Event>> result = new DeferredResult<>(28000L, List.of());
  eventBus.subscribe(lastId, events -> result.setResult(events));
  return result;   // held open until event arrives or 28s timeout
}

// Characteristics:
// ✓ Works through all proxies and firewalls (plain HTTP)
// ✗ Double latency on each event (server must wait, client must reconnect)
// ✗ Server holds many threads/connections open

Server-Sent Events (SSE)

SSE is a W3C standard for server-to-client streaming over a single HTTP connection. The server sends text/event-stream responses; the browser's EventSource API handles reconnection automatically. SSE is one-way (server→client only) and works through HTTP/2 and most proxies.

SSE server and client implementation
// SSE — server side (Spring Boot):
@GetMapping(value = "/api/feed", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamFeed(@RequestParam String userId) {
  SseEmitter emitter = new SseEmitter(0L);  // no timeout
  sseRegistry.register(userId, emitter);
  emitter.onCompletion(() -> sseRegistry.remove(userId));
  emitter.onError(e -> sseRegistry.remove(userId));
  return emitter;
}

// Push event to specific user:
emitter.send(SseEmitter.event()
    .id(String.valueOf(eventId))
    .name("notification")
    .data(objectMapper.writeValueAsString(notification)));

// SSE event format (text/event-stream):
// id: 42
// event: notification
// data: {"type":"new_message","from":"Rahul","text":"Hey!"}
//
// (blank line = event delimiter)

// SSE — client side (browser):
const es = new EventSource('/api/feed?userId=123')
es.addEventListener('notification', e => {
  const n = JSON.parse(e.data)
  showNotification(n)
})
// EventSource auto-reconnects on disconnect, sends Last-Event-ID header

WebSocket

WebSocket upgrades an HTTP/1.1 connection to a persistent, full-duplex TCP channel. Both client and server can send messages at any time without waiting for a request. WebSocket uses its own framing protocol (not HTTP) once the upgrade handshake completes.

WebSocket upgrade handshake and Spring Boot STOMP config
// WebSocket upgrade handshake (HTTP → WS):
// Client → Server:
GET /ws HTTP/1.1
Host: api.aicancode.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

// Server → Client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
// ← from here, raw WebSocket frames (not HTTP)

// Spring Boot WebSocket (STOMP over WebSocket):
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/ws").withSockJS();  // SockJS fallback
  }
  @Override
  public void configureMessageBroker(MessageBrokerRegistry registry) {
    registry.enableSimpleBroker("/topic", "/queue");
    registry.setApplicationDestinationPrefixes("/app");
  }
}

// Push to all subscribers of a topic:
messagingTemplate.convertAndSend("/topic/live-feed", event);

Comparison & When to Use Each

The right choice depends on directionality, latency requirements, and infrastructure. SSE covers most server-push use cases with far less complexity than WebSocket. WebSocket is needed only for true bidirectional real-time communication.

Long polling vs SSE vs WebSocket decision guide
// Comparison table:
// ┌──────────────┬──────────────┬──────────────────┬──────────────────────┐
// │              │ Long Polling │ SSE              │ WebSocket            │
// ├──────────────┼──────────────┼──────────────────┼──────────────────────┤
// │ Direction    │ S→C (hacky)  │ S→C only         │ Full-duplex (S↔C)   │
// │ Protocol     │ HTTP         │ HTTP             │ WS (after upgrade)   │
// │ Auto-reconnect│ Manual      │ Yes (EventSource)│ Manual / library     │
// │ Load balancer│ Any          │ Any HTTP LB      │ Needs sticky or WS-  │
// │              │              │                  │ aware proxy          │
// │ Overhead     │ High (HTTP   │ Low (single conn)│ Lowest (raw frames)  │
// │              │ headers each)│                  │                      │
// │ Complexity   │ Low          │ Low              │ Medium–High          │
// └──────────────┴──────────────┴──────────────────┴──────────────────────┘

// Choose Long Polling: legacy systems, must work through strict proxies,
//                      very infrequent events
// Choose SSE:          dashboards, live feeds, notifications, progress bars
//                      (server pushes, client rarely sends)
// Choose WebSocket:    chat, collaborative editing, multiplayer games,
//                      live trading — true bidirectional low-latency

Key Points to Remember

  • 1Long polling holds the HTTP request open until data arrives, then the client immediately re-requests — works everywhere but doubles latency.
  • 2SSE (EventSource) is a single persistent HTTP stream; the browser auto-reconnects and sends Last-Event-ID for resumability.
  • 3WebSocket provides full-duplex communication over a single TCP connection — lowest overhead, but requires WS-aware proxies and manual reconnection logic.
  • 4SSE is the right default for most server-push use cases (notifications, feeds); WebSocket only when the client also sends frequent messages.
  • 5WebSocket load balancing requires sticky sessions or a shared pub/sub backend (Redis) because the persistent connection must reach the same server.

Interview Questions

Sign in to ask Aria
1

What is the difference between SSE and WebSocket?

MediumThoughtWorks
2

When would you choose long polling over SSE?

MediumTCS
3

How do you scale WebSocket connections across multiple server instances?

HardRazorpay
4

How does the WebSocket upgrade handshake work?

MediumAmazon
5

Design a live notification system for 1 million concurrent users — which protocol would you use and why?

HardEqual Experts

Ask Aria about Long Polling vs SSE vs WebSocket

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…