Wednesday, May 27, 2026Today's Paper

M Blog

Nginx Proxy WebSocket: The Ultimate Guide
May 27, 2026 · 7 min read

Nginx Proxy WebSocket: The Ultimate Guide

Master Nginx WebSocket proxy configurations for real-time applications. Learn about upgrade headers, timeouts, SSL/TLS (WSS), and load balancing for seamless bidirectional communication.

May 27, 2026 · 7 min read
NginxWebSocketsReverse Proxy

Nginx Proxy WebSocket: Your Essential Guide to Real-Time Communication

WebSocket technology has revolutionized real-time web applications, enabling persistent, two-way communication between clients and servers. Whether you're building a chat app, a live dashboard, or a collaborative tool, Nginx can act as a robust proxy for your WebSocket connections. This guide will demystify the process of configuring Nginx for WebSocket proxying, covering essential directives, common pitfalls, and best practices for performance and security.

Understanding WebSocket Handshake and Nginx's Role

Unlike traditional HTTP requests, which are typically short-lived and serve a single purpose, WebSocket connections begin as an HTTP request but then upgrade to a persistent, full-duplex protocol. This upgrade mechanism, defined in RFC 6455, requires special handling by intermediary servers like Nginx.

Here's a simplified breakdown of the process:

  1. Client Initiates: The client sends an HTTP request to the server, including specific headers like Upgrade: websocket and Connection: Upgrade.
  2. Server Responds: If the server supports WebSockets, it responds with a 101 Switching Protocols status code, signaling the upgrade.
  3. Connection Established: The connection is now upgraded to a WebSocket connection, allowing for continuous, bidirectional data flow without the overhead of repeated HTTP requests.

Nginx, as a reverse proxy, sits between the client and your backend WebSocket server. Its primary role is to facilitate this upgrade handshake and then tunnel the WebSocket traffic. However, due to how Nginx handles hop-by-hop headers (headers that apply only to a single network hop), it needs explicit configuration to pass the Upgrade and Connection headers to the backend server. Without this, the handshake fails, often resulting in a 400 Bad Request or 426 Upgrade Required error.

Core Nginx Configuration for WebSocket Proxying

To enable Nginx to proxy WebSocket connections effectively, several key directives are crucial within your location block:

  • proxy_http_version 1.1;: WebSockets require HTTP/1.1 for the upgrade mechanism. Older HTTP versions do not support this.

  • proxy_set_header Upgrade $http_upgrade;: This directive explicitly forwards the Upgrade header from the client to the backend server. Nginx, by default, strips this header.

  • proxy_set_header Connection "upgrade";: Similarly, this directive forwards the Connection header, signaling to the backend that the connection should be upgraded. The value is set to "upgrade" to match the client's request.

  • proxy_pass http://your_backend_server;: This directive specifies the address of your backend WebSocket application.

Example Basic Configuration:

http {
    upstream websocket_backend {
        server 127.0.0.1:3000;
        keepalive 32;
    }

    server {
        listen 80;
        server_name yourdomain.com;

        location /ws/ {
            proxy_pass http://websocket_backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # Other locations for regular HTTP traffic
        location / {
            # ... your regular proxy settings ...
        }
    }
}

Handling Timeouts for Long-Lived Connections

WebSocket connections are designed to be long-lived, enabling continuous communication. However, Nginx has default timeouts that can prematurely close these persistent connections if they remain idle. The most common issue is connections dropping after approximately 60 seconds.

To address this, you need to increase the proxy_read_timeout directive:

  • proxy_read_timeout 3600s; (or a higher value, e.g., 1 hour): This setting prevents Nginx from closing the connection if no data is received within the specified duration.

It's also recommended to increase proxy_send_timeout and proxy_connect_timeout for very long-lived connections.

Important Note: While increasing Nginx timeouts is crucial, your backend application should also implement ping/pong mechanisms to keep the connection alive and check its status periodically, with intervals shorter than the Nginx timeout.

Secure WebSocket Connections (WSS/SSL/TLS)

For production environments, securing your WebSocket traffic with SSL/TLS (using the wss:// protocol) is essential. Nginx excels at handling SSL termination, allowing your backend servers to communicate over unencrypted ws:// while clients connect securely via wss://.

This is achieved by configuring a standard SSL server block in Nginx:

server {
    listen 443 ssl http2;
    server_name ws.yourdomain.com;

    ssl_certificate /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    # ... other SSL settings ...

    location /ws/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# Optional: Redirect HTTP to HTTPS
server {
    listen 80;
    server_name ws.yourdomain.com;
    return 301 https://$host$request_uri;
}

In this setup, Nginx handles the TLS encryption/decryption, and then forwards the traffic to your backend application over plain HTTP/WebSocket.

Load Balancing WebSocket Servers

When you need to scale your WebSocket application, load balancing across multiple backend servers becomes necessary. WebSocket connections are stateful, meaning a client should ideally maintain a persistent connection with the same backend server throughout its session. This is achieved using sticky sessions (also known as session affinity).

NGINX Plus and some Nginx open-source configurations support IP hashing for sticky sessions:

  • ip_hash; (within the upstream block): This ensures that requests from the same IP address are consistently directed to the same backend server.

Example with Load Balancing:

upstream websocket_servers {
    ip_hash;
    server backend1.example.com:3000;
    server backend2.example.com:3000;
    server backend3.example.com:3000;
}

server {
    listen 80;
    server_name yourdomain.com;

    location /ws/ {
        proxy_pass http://websocket_servers;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        # ... other headers ...
    }
}

It's important to note that WebSocket connections cannot be transparently failed over; clients must reconnect if a backend server becomes unavailable.

Advanced Configurations and Troubleshooting

1. Handling Both HTTP and WebSocket Traffic on the Same Port:

If your application serves both regular HTTP requests and WebSocket connections on the same domain and port, you can use the map directive to dynamically set the Connection header based on whether an Upgrade header is present:

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 80;
        server_name yourdomain.com;

        location / {
            proxy_pass http://your_backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade; # Use the mapped variable
            # ... other headers ...
        }
    }
}

This setup ensures that regular HTTP requests get Connection: close, while WebSocket requests correctly receive Connection: upgrade.

2. Performance Optimization:

  • Disable Buffering: For high-traffic WebSocket locations, disabling proxy buffering can sometimes improve performance by reducing latency. Add proxy_buffering off; to the relevant location block.
  • TCP_NODELAY: Nginx automatically enables TCP_NODELAY when switching to upgrade mode, which is beneficial for low-latency communication.
  • Worker Connections: Ensure your worker_connections setting in the events block is adequately high to handle the expected number of concurrent connections.

3. Common Troubleshooting Steps:

  • 400 Bad Request / 426 Upgrade Required: This almost always points to missing or incorrect Upgrade and Connection headers, or an incorrect proxy_http_version. Double-check your proxy_set_header directives and ensure proxy_http_version 1.1 is set.
  • Connection Drops after 60 Seconds: Increase proxy_read_timeout.
  • 502 Bad Gateway: The backend server is unreachable or not running. Verify its status and the proxy_pass address.
  • Logs: Always check Nginx's error logs (/var/log/nginx/error.log) for detailed information. Enabling debug logging can provide even more insights.

Conclusion

Configuring Nginx as a WebSocket proxy is fundamental for building modern, real-time web applications. By understanding the WebSocket handshake, implementing the correct Nginx directives for header forwarding, managing timeouts, and securing connections with SSL/TLS, you can ensure seamless, reliable, and performant bidirectional communication. Remember to always test your configuration thoroughly and consult your Nginx error logs when troubleshooting.

FAQ

**Q: Why do my WebSocket connections drop after 60 seconds?

A:** Nginx has a default proxy_read_timeout of 60 seconds. If no data is exchanged within this period, Nginx closes the connection. You need to increase this timeout (e.g., proxy_read_timeout 3600s;) in your Nginx configuration. Additionally, ensure your WebSocket application sends periodic ping/pong frames to keep the connection active.

**Q: How do I fix the "400 Bad Request" error when proxying WebSockets with Nginx?

A:** This error typically occurs because Nginx, by default, doesn't forward the necessary Upgrade and Connection headers required for the WebSocket handshake. You must explicitly set these headers using proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade"; in your Nginx location block. Ensure proxy_http_version 1.1; is also set.

**Q: Can Nginx proxy both regular HTTP traffic and WebSocket traffic?

A:** Yes, Nginx can handle both. You can configure different location blocks for HTTP and WebSocket endpoints, or use the map directive to dynamically handle both types of traffic within the same location if your application supports it.

**Q: How do I enable SSL/TLS for WebSocket connections (WSS) with Nginx?

A:** Configure a standard Nginx server block with listen 443 ssl; and provide your SSL certificate and key. Then, use proxy_pass to direct WebSocket traffic to your backend. Nginx will handle TLS termination, allowing your backend to use plain ws://.

**Q: What are the performance implications of using Nginx for WebSocket proxying?

A:** Nginx is highly performant and scalable for WebSocket proxying. Tests have shown it can handle tens of thousands of concurrent connections with minimal CPU and memory usage. Performance can be further optimized by disabling proxy buffering for WebSocket locations and ensuring adequate worker_connections are configured.

Related articles
Pak vs NZ Match Live Today: T20 World Cup 2026 Super Eights - How to Watch & More
Pak vs NZ Match Live Today: T20 World Cup 2026 Super Eights - How to Watch & More
Get the latest on the Pak vs NZ match live today, including T20 World Cup 2026 Super Eights updates, live streaming info, head-to-head records, and match analysis.
May 27, 2026 · 5 min read
Read →
Smart Gadgets: The Ultimate Guide to Modern Tech
Smart Gadgets: The Ultimate Guide to Modern Tech
Explore the world of smart gadgets, from AI-powered wearables and kitchen appliances to home security systems. Discover how these innovations are shaping our lives and making everyday tasks easier.
May 27, 2026 · 6 min read
Read →
The Ultimate Taco Recipe: From Seasoning to Fillings
The Ultimate Taco Recipe: From Seasoning to Fillings
Discover the best taco recipe, from homemade seasoning blends and savory ground beef to chicken and vegetarian options. Perfect for any occasion!
May 27, 2026 · 5 min read
Read →
Spotify Soundtrap: Your Guide to Music & Podcast Creation
Spotify Soundtrap: Your Guide to Music & Podcast Creation
Unlock your creative potential with Spotify Soundtrap. Explore its features for music production and podcasting, from collaboration to professional mixing.
May 27, 2026 · 5 min read
Read →
LeoLabs Space: Tracking Satellites & Debris
LeoLabs Space: Tracking Satellites & Debris
Explore LeoLabs space, a global leader in space domain awareness. Discover their advanced radar network, satellite tracking, and debris monitoring services for a safer LEO.
May 27, 2026 · 4 min read
Read →
You May Also Like