WebSockets enable persistent, bidirectional connections between client and server — used for chat apps, live notifications, and real-time dashboards. Proxying them through Nginx requires specific configuration beyond standard HTTP proxying.
Why WebSockets Need Special Configuration
A WebSocket connection starts as a standard HTTP request but then "upgrades" to a persistent, long-lived connection — Nginx's default proxy behavior doesn't automatically support this upgrade without explicit configuration.
Basic WebSocket Proxy Configuration
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
proxy_http_version 1.1 is required for WebSocket support (1.0 doesn't support it), and the Upgrade/Connection headers signal the protocol upgrade through the proxy.
Handling Mixed HTTP and WebSocket Traffic on the Same Backend
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
This pattern correctly handles both regular HTTP requests and WebSocket upgrade requests through the same location block.
Increasing Timeout for Long-Lived Connections
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
WebSocket connections often stay open for extended periods — Nginx's default proxy timeouts (often much shorter) would prematurely close idle-but-legitimate connections without this adjustment.
Load Balancing WebSocket Connections
upstream websocket_backend {
ip_hash;
server 10.0.0.10:8080;
server 10.0.0.11:8080;
}
ip_hash ensures a given client consistently reaches the same backend server across requests — important for WebSocket connections, which are stateful and tied to a specific server instance, unlike typical stateless HTTP requests.
Testing WebSocket Connectivity
wscat -c wss://yourdomain.com/ws/
A simple command-line WebSocket client tool for testing connectivity directly, useful for isolating whether an issue is in your Nginx configuration or the application itself.
Securing WebSocket Connections (WSS)
Ensure WebSocket connections use wss:// (WebSocket Secure, over TLS) rather than plain ws:// in production — this works automatically once your Nginx server block itself has SSL configured, since the WebSocket upgrade happens over the same already-secured connection.
Common Errors
WebSocket connection immediately closes or fails to upgrade — verify proxy_http_version 1.1 and the Upgrade/Connection headers are correctly set; a missing or incorrect one of these is the most common cause.
Connection drops after a period of inactivity — increase proxy_read_timeout/proxy_send_timeout, or implement application-level ping/pong keepalive messages to prevent the connection from appearing idle.
Continue Reading
- How to Configure Nginx as a Reverse Proxy for Node.js/Docker Apps
- How to Set Up Basic Load Balancing with Nginx
- How to Build a Simple Chat Application with WebSockets on a VPS
Browse more articles in Web Servers.