xhr poll error in Socket.IO default xhr-polling transport under concurrent load
0 reputation · 07 Sept 2021, 05:15 UTC
0 reputation · 07 Sept 2021, 05:15 UTC
Goal: Identify the root cause of latency spikes that appear only when many Socket.IO clients use the default xhr‑polling transport, as indicated by recurring 'xhr poll error' messages in client logs.
Constraints: The server runs with the default 10‑second heartbeat, exponential reconnection back‑off (starting at 250 ms), a limited thread pool, the in‑memory adapter unless Redis is configured, a maxHttpBufferSize of 1 MB, and no per‑message compression enabled by default.
Uncertainty: It is unclear whether increasing maxHttpBufferSize, enabling per‑message compression, or adjusting heartbeat/timeouts will reduce the xhr poll errors, or whether the observed latency is primarily due to thread‑pool exhaustion and Redis adapter queueing under concurrent load.
Does raising maxHttpBufferSize decrease the frequency of xhr poll errors under heavy concurrent polling?
Does enabling per‑message compression mitigate latency spikes caused by large payloads?
Is the latency primarily driven by server thread‑pool saturation rather than transport‑level configuration?
35275 reputation · 07 Sept 2021, 11:12 UTC
No — raising maxHttpBufferSize will not meaningfully reduce xhr poll error frequency under heavy concurrent polling, and enabling per-message compression is more likely to make things worse than better. The evidence points to server-side resource saturation (thread pool / event-loop pressure from thousands of short-lived HTTP requests) as the primary driver, not transport-level configuration.
maxHttpBufferSize (default 1 MB) only matters when a single message or polling response actually approaches that limit. An xhr poll error is a client-side signal that a polling request failed — typically due to a timeout, a dropped connection, or a 5xx response from the server or proxy — not because a payload was rejected for size. Unless your logs show payloads near 1 MB, raising the limit changes nothing about failure rates. It only raises the ceiling for memory a single oversized request can consume, which is mildly risky under load.
Per-message compression shrinks payloads on the wire, which can help if your latency spikes correlate with large messages on constrained bandwidth. But compression costs CPU on every message for every client. With xhr-polling, that CPU cost is paid on every poll cycle, not just when data flows. Under concurrent load — where your suspected bottleneck is already CPU/thread-pool saturation — enabling compression can amplify the very exhaustion causing the errors. Treat it as a targeted optimization for large-payload workloads, verified by measurement, not a general remedy.
XHR polling is structurally expensive. Each client issues a full HTTP request/response cycle for every poll, and with many clients the request rate multiplies fast. Consequences that match your symptoms:
xhr poll error on the client.perf_hooks.monitorEventLoopDelay(), or clinic doctor) or thread-pool utilization during a spike. If errors align with saturation, transport tuning is confirmed as secondary.Upgrade headers). WebSockets eliminate the per-poll HTTP cycle entirely.One detail would sharpen this recommendation: the HTTP status (or absence of one) on the failed poll requests. If failures are clean 4xx responses rather than timeouts, the diagnosis above would need revisiting toward payload or framing issues.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.