Long Polling vs SSE vs WebSockets
debt(d7/e3/b3/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints confirm automated detection is 'no', with only a code_pattern hint (JavaScript polling every second with Ajax). There is no tool in detection_hints.tools that catches this — identifying the wrong real-time mechanism (e.g. polling instead of SSE, or WebSocket instead of SSE) requires a developer to recognize the pattern in review or notice inefficiency in runtime testing.
Closest to 'simple parameterised fix' (e3). The quick_fix says to swap to SSE for server-to-client push, which is a clear replacement pattern. However, it involves replacing the client-side polling logic and server-side response format, touching both ends but within a localized component — more than a one-liner but not a multi-file architectural change.
Closest to 'localised tax' (b3). The applies_to scope is web contexts only, and the choice affects the real-time communication layer of a single feature or component. Picking the wrong mechanism (e.g. WebSocket when SSE suffices) adds complexity to that component but doesn't propagate a structural burden across the rest of the codebase.
Closest to 'notable trap' (t5). The misconception field states developers believe 'WebSockets are always better than SSE,' which is a documented gotcha — SSE has proxy/firewall compatibility and auto-reconnection advantages that most developers learn only after hitting production issues. It's a well-known trap but not one that contradicts a similar concept in another ecosystem, so t5 is appropriate.
Also Known As
TL;DR
Explanation
Long polling: client holds HTTP request open, server responds when data is available, client reconnects immediately. Simple but high latency from reconnect overhead. SSE: browser opens persistent connection, server pushes text events with built-in reconnection and event IDs. One-directional, HTTP-compatible. WebSocket: full-duplex TCP after HTTP upgrade — bidirectional, binary and text, low latency. PHP: SSE with chunked transfer encoding + flush(). WebSockets via ReactPHP or Ratchet.
Common Misconception
Why It Matters
Common Mistakes
- Long polling with short timeouts — defeats the purpose
- SSE without event IDs — client misses events during disconnection
- WebSocket when SSE suffices — added complexity for no benefit
- No heartbeat — proxies close idle connections after 30-90 seconds
Code Examples
// 1 request per second per user — expensive:
setInterval(() => {
fetch('/api/updates').then(r => r.json()).then(update);
}, 1000);
// SSE — persistent, automatic reconnection:
// PHP:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no'); // Disable nginx buffering
while (true) {
echo "id: {$id}\ndata: " . json_encode(getLatest()) . "\n\n";
ob_flush(); flush();
if (connection_aborted()) break;
sleep(1);
}
// JavaScript:
const es = new EventSource('/api/stream');
es.addEventListener('update', e => update(JSON.parse(e.data)));