LEARNING OBJECTIVES ⌵
- Understand the 6-connection per-origin limitation of HTTP/1.1 for SSE.
- Leverage HTTP/2 and HTTP/3 multiplexing to stream hundreds of concurrent SSE channels on a single TCP connection.
- Configure reverse proxies (Nginx, Envoy, Cloudflare) for unbuffered chunked SSE proxying.
- Implement load balancing, heartbeats, and cluster architecture for millions of live SSE connections.
📖 The Mental Model & Story
In HTTP/1.1, opening a Server-Sent Event stream is like monopolizing an entire single-lane highway. Browsers restrict origins to a maximum of 6 concurrent TCP connections. If you open 6 SSE streams across multiple tabs, the 7th tab hangs indefinitely, unable to load basic CSS, JS, or images!
With HTTP/2 multiplexing, that single highway becomes a quantum teleportation transit system. Thousands of bidirectional data streams and SSE pipelines share a single TCP socket via interleaved binary frames, completely eliminating connection starvation.
HTTP/1.1 (Connection Starvation Trap):
Tab 1: [SSE Stream 1] ===================> Socket 1 (LOCKED)
Tab 2: [SSE Stream 2] ===================> Socket 2 (LOCKED)
Tab 3: [SSE Stream 3] ===================> Socket 3 (LOCKED)
Tab 4: [SSE Stream 4] ===================> Socket 4 (LOCKED)
Tab 5: [SSE Stream 5] ===================> Socket 5 (LOCKED)
Tab 6: [SSE Stream 6] ===================> Socket 6 (LOCKED)
Tab 7: [Page Load / CSS / Image] ========> BLOCKED / HANGS FOREVER! ❌
HTTP/2 (Multiplexed Architecture):
Tab 1..100: [All Streams + Assets] ====> [SINGLE TCP SOCKET (Multiplexed)] ====> Server ✅
Technical Deep Dive & Specifications
Reverse Proxy Configuration (Nginx)
To prevent Nginx or intermediate proxies from buffering SSE stream payloads into 4KB batches, disable proxy buffering:
location /api/live-stream/ {
proxy_pass http://sse_backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
# Critical SSE proxy headers
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h;
chunked_transfer_encoding on;
# Enable HTTP/2 on the outer server block
http2 on;
}
💻 Interactive Code Playground
🏋️ Hands-On Exercise
Scenario: Add a client-side heartbeat timeout detector. If no message or ping is received within 35 seconds, force-reconnect the EventSource.
- ⚠️ Cloudflare 100-second Timeout: Cloudflare drops idle HTTP streams after 100 seconds. Ensure the server emits a heartbeat comment (
:\n\n) every 15–30 seconds. - 💡 HTTP/2 is Mandatory in Production: Never deploy enterprise SSE over raw HTTP/1.1; enforce HTTPS with ALPN to negotiate HTTP/2 or HTTP/3 automatically.
📌 Key Takeaways
- HTTP/1.1 limits browsers to 6 concurrent streams per domain.
- HTTP/2 removes connection limits through stream multiplexing on a single TLS connection.
- Always disable proxy buffering (
X-Accel-Buffering: noorproxy_buffering off) when serving SSE. - --