Skip to content

17 Load Balancing

DodaTech 3 min read

title: "WebSocket Load Balancing" description: "Load balance WebSocket connections across multiple servers using Nginx, HAProxy, AWS ALB, and Kubernetes ingress. Learn connection distribution, health checks, scaling strategies, and connection draining." weight: 17 date: 2026-06-28 lastmod: 2026-06-28 tags: [api-development, websocket] }

Load balancing WebSocket connections requires specialized configuration. Unlike HTTP, WebSocket connections are long-lived. Load balancers must handle the upgrade handshake, maintain connection affinity, and implement WebSocket-aware health checks.

What You'll Learn

  • Nginx WebSocket load balancing
  • HAProxy WebSocket configuration
  • AWS ALB WebSocket support
  • Kubernetes ingress for WebSocket
  • Health checks and connection draining

Why It Matters

WebSocket load balancing differs from HTTP load balancing. Standard round-robin without affinity breaks WebSocket state. Proper configuration ensures high availability and even connection distribution.

Real-World Use

Nginx handles WebSocket for many high-traffic applications. HAProxy is popular for WebSocket in financial services. Kubernetes with nginx-ingress supports WebSocket natively.

flowchart LR
    Internet[Internet] --> LB[Load Balancer]
    LB --> Server1[WebSocket Server 1]
    LB --> Server2[WebSocket Server 2]
    LB --> Server3[WebSocket Server 3]
    Server1 --> Session1[Client A]
    Server2 --> Session2[Client B]
    Server3 --> Session3[Client C]
    Server1 --> Session4[Client D]

Teacher Mindset

Choose a load balancer that supports HTTP/1.1 upgrade and long-lived connections. Configure health checks to ping the WebSocket endpoint. Use connection draining for graceful shutdown.

Code Examples

# Example 1: Nginx WebSocket configuration
upstream websocket {
    hash $remote_addr consistent;
    server ws1.example.com:8080 max_fails=3 fail_timeout=30s;
    server ws2.example.com:8080 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name ws.example.com;

    location /ws {
        proxy_pass http://websocket;
        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-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}
# Example 2: HAProxy WebSocket configuration
frontend ws_frontend
    bind *:80
    default_backend ws_backend

backend ws_backend
    balance leastconn
    option http-server-close
    option log-health-checks

    # WebSocket health check
    option httpchk GET /health
    http-check expect status 200

    server ws1 ws1.example.com:8080 check inter 10s fall 3 rise 2
    server ws2 ws2.example.com:8080 check inter 10s fall 3 rise 2

    # Enable WebSocket support
    acl is_websocket hdr(Upgrade) -i websocket
    acl is_websocket hdr_beg(Host) -i ws
    use_backend ws_backend if is_websocket
# Example 3: Kubernetes ingress for WebSocket
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ws-ingress
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "86400"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "86400"
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
spec:
  rules:
  - host: ws.example.com
    http:
      paths:
      - path: /ws
        pathType: Prefix
        backend:
          service:
            name: ws-service
            port:
              number: 8080

Common Mistakes

  • Using HTTP health checks that do not test WebSocket readiness
  • Setting proxy timeouts too low, causing premature disconnection
  • Not configuring sticky sessions for stateful WebSocket servers
  • Load balancing without a shared state layer (Redis pub/sub)
  • During rolling updates, not draining connections before shutdown

Practice

  1. Set up Nginx to load balance WebSocket across two servers.
  2. Configure HAProxy with leastconn balancing and WebSocket health checks.
  3. Add a third server and verify even connection distribution.
  4. Test rolling update with connection draining.
  5. Challenge: Benchmark connection capacity with and without load balancing.

FAQ

Can I use round-robin for WebSocket?

Not without sticky sessions. Round-robin distributes connections but subsequent frames may go to a different server.

What is connection draining?

Connection draining lets in-flight requests complete before shutting down a server. For WebSocket, this means waiting for clients to reconnect.

How do I health check WebSocket servers?

Serve a simple health endpoint (GET /health) on the same port. The load balancer checks this endpoint regularly.

Does HTTP/2 affect WebSocket load balancing?

HTTP/2 does not support the WebSocket upgrade mechanism. Use HTTP/1.1 for WebSocket or HTTP/2 CONNECT for WebSocket over HTTP/2.

How many WebSocket connections per server?

Depends on message frequency and payload size. Typical limits are 1000-10000 connections per Node.js server instance.

Mini Project

Deploy a WebSocket application with Nginx load balancing two server instances. Configure health checks, sticky sessions, and connection draining. Verify that clients reconnect when a server goes down.

What's Next

Next, you will learn about WebSocket security including origin checking and input validation.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro