intermediate

SSE and long polling

Use one-way streaming or polling when browser compatibility, proxies, retry semantics, and simpler infrastructure matter.

When the server pushes updates but the client only needs **one-way** streams, SSE and long polling are often simpler than WebSockets.

**Server-Sent Events (SSE)** — HTTP response stays open; server writes `text/event-stream` frames:

					GET /events/orders
Accept: text/event-stream

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache

event: order.created
id: 1024
data: {"orderId":"ord_9"}

: keepalive

event: order.updated
id: 1025
data: {"orderId":"ord_9","status":"SHIPPED"}
				

Browser `EventSource` auto-reconnects and sends `Last-Event-ID` for resume. Proxies must not buffer SSE indefinitely — configure nginx/load balancers.

**Long polling**: client requests; server holds until event or timeout, then client immediately reconnects. Higher overhead, works everywhere HTTP works.

| | SSE | Long polling | WebSocket | |---|-----|--------------|-----------| | Direction | server → client | server → client | bidirectional | | Browser API | EventSource | fetch/XHR | WebSocket | | Binary | no (text) | yes | yes |

On interviews: pick SSE for notifications feeds, long polling for legacy constraints, and name proxy buffering pitfalls.

Common pitfalls: missing Last-Event-ID handling, no keepalive comments, CORS misconfig on EventSource, and long poll timeouts without client backoff.

The trade-off is simplicity and HTTP compatibility versus bidirectional needs — do not default to WebSockets for one-way feeds.

Checklist:

  • SSE for one-way text events with resume ids.
  • Keepalive and proxy timeout alignment.
  • Exponential backoff on client reconnect.
  • Long poll only when SSE is blocked.