Separate connection establishment from continuity
A WebSocket begins with an HTTP handshake and then maintains a longer-lived connection. Failure before the protocol upgrade is different from a disconnect after an idle period. A dashboard may load its ordinary HTTP pages successfully while its live updates fail because the proxy treats the upgrade or connection lifetime differently.
This guide covers a Node.js application behind Nginx. A CDN, ingress controller or cloud load balancer can add further limits. List the complete path before changing a timeout on the first component you recognize. Browser reconnects can hide repeated failures while increasing connection churn on the server.
Setup: map the actual upgrade route
Record the public WebSocket URL, path rewrite, TLS termination point, upstream address and authentication method. Confirm that the Node.js server receives the intended route. The Nginx documentation explains that hop-by-hop upgrade headers need explicit proxy handling and describes the protocol-switch response. Match its HTTP-version guidance to the installed Nginx release.
Establish an isolated test channel that contains no customer events. Capture handshake status, connection identifiers, open and close timestamps, and sanitized close reasons. Configure application-level heartbeat behavior deliberately. Merely keeping a TCP socket open does not prove that both endpoints can still process useful messages.
Illustrative incident: every quiet dashboard reconnects
In an illustrative monitoring application, active dashboards work, but quiet dashboards reconnect after a repeatable idle interval. The upgrade succeeds, then an intermediary closes a connection that has seen no upstream data. This is a teaching example rather than a measured production incident.
Compare an active test channel with a quiet one and identify the first component recording closure. Nginx documents an idle upstream-read timeout and notes that suitable ping traffic can keep the connection active. Other intermediaries may have independent policies, so do not attribute every regular disconnect to Nginx alone.
Troubleshooting: locate the failing phase
| Symptom | Evidence | Next check |
|---|---|---|
| Upgrade never succeeds | HTTP status and upstream route | Verify upgrade forwarding and authentication |
| Quiet sessions close consistently | Idle interval and intermediary logs | Review timeout and heartbeat expectations |
| Reconnect succeeds but events disappear | Last accepted event identity | Check replay or state resynchronization |
| Deployments cause a reconnect storm | Close behavior and client retry timing | Bound reconnect concurrency and jitter |
Avoid logging authorization cookies or full event payloads. A connection identifier and event sequence marker usually provide enough evidence to distinguish transport loss from application processing failure.
Corrective action and reconnect design
Correct the specific proxy route and headers, then choose heartbeat and timeout settings that fit the application and every intermediary. Do not increase every timeout indefinitely. Dead connections should eventually be detected and released so they cannot consume capacity forever.
Give clients a bounded retry strategy with jitter and a way to resynchronize state. A reconnected socket is not evidence that events missed during disconnection were recovered. For important updates, use a durable event identity or reload the authoritative state according to the product contract. Review authorization again when establishing a new connection; connection continuity must not preserve permissions that have been revoked.
Verification and operational handover
Test handshake rejection, a quiet healthy session, a failed heartbeat, a proxy restart and a rolling application release. Observe both server resource cleanup and the user's eventual view. Verify that repeated reconnects cannot create duplicate subscriptions or multiple active handlers for one screen.
An internal SLO can measure useful update freshness and successful session recovery, rather than socket uptime alone. A contractual SLA needs explicit network and client assumptions. The SOP should include the route map, timeout owners, heartbeat definition, reconnect dashboard and evidence required before changing connection limits.
Explore Node.js development and network architecture.
Technical reference
Nginx WebSocket proxying, reviewed 19 October 2026. Follow documentation matching the installed product version.