Networking

WebSocket connections

5 min readUpdated April 2026

StackBlaze fully supports WebSockets with zero extra configuration. The Nginx Ingress is pre-configured with proxy_read_timeout 3600 and proxy_send_timeout 3600, and the Upgrade and Connection headers are forwarded by default on every web service.

The one thing to be aware of when scaling: WebSocket connections are long-lived and stateful. A client that opens a connection to pod A will break if the next HTTP upgrade request lands on pod B. The solution is sticky sessions, which you can toggle from the dashboard without writing any Kubernetes YAML.

WebSocket server (Node.js)

server.js, ws library

import { WebSocketServer } from 'ws';

import http from 'node:http';

const server = http.createServer();

const wss = new WebSocketServer({ server });

wss.on('connection', (ws) => {

ws.on('message', (data) => {

ws.send(`echo: ${data}`);

});

});

// PORT is injected by StackBlaze at runtime

server.listen(process.env.PORT ?? 8080);

Browser client

client.ts, browser

// wss:// is available automatically, no extra config

const ws = new WebSocket(

'wss://my-app.stackblaze.app/socket'

);

ws.addEventListener('open', () => {

ws.send('hello');

});

ws.addEventListener('message', (e) => {

console.log(e.data);

});

WebSocket connection path

wss://Upgradesticky
Browser

new WebSocket()

wss:// upgrade

Nginx Ingress

TLS terminated

timeout 3600 s

K8s Service

ClusterIP

sessionAffinity

Pod

ws handler

long-lived conn

Under the hood

StackBlaze pre-configures the Nginx Ingress with the following annotations on every web service. You do not need to set these yourself:

  • nginx.ingress.kubernetes.io/proxy-read-timeout: "3600", keeps the upstream connection alive for up to one hour of inactivity, preventing the Nginx worker from closing idle WebSocket connections.
  • nginx.ingress.kubernetes.io/proxy-send-timeout: "3600", matches the read timeout so bidirectional long-lived streams are not prematurely dropped.
  • Upgrade & Connection headers: Nginx forwards the Upgrade: websocket and Connection: Upgrade headers to the upstream pod, completing the HTTP/1.1 upgrade handshake.
  • sessionAffinity: ClientIP: when sticky sessions are enabled, the Kubernetes Service routes all requests from the same client IP to the same pod. The affinity timeout defaults to 10 800 seconds (3 hours) and is configurable in the Networking tab.

Step by step

01

Build your WebSocket server normally

Write your WebSocket server using any Node.js library, the native "ws" package, Socket.io, or uWebSockets.js. StackBlaze does not require any special adapter or proxy library. The examples below show both a raw ws server and a Socket.io server.

02

Deploy as a Web Service - no special type needed

Create a Web Service in the StackBlaze dashboard and point it at your repo. There is no dedicated "WebSocket" service type. StackBlaze provisions a standard Deployment + Nginx Ingress with the correct proxy headers pre-configured, Upgrade and Connection are forwarded automatically.

03

Connect via your wss:// URL

Your service URL (e.g. my-app.stackblaze.app) is automatically available over HTTPS and WSS. TLS is terminated at the Ingress. Use "wss://my-app.stackblaze.app/socket" in your client, no extra config on your end. Custom domains work identically.

04

Enable sticky sessions for horizontal scaling

WebSocket connections are long-lived. If you scale to multiple replicas, subsequent requests from the same client must reach the same pod or the connection breaks. In the dashboard, open Networking → enable "Sticky Sessions". This sets sessionAffinity: ClientIP on the Kubernetes Service.