Most of the communcation on web happens over HTTP protocol. With HTTP, client and server communicate through a
request-response model. The client sends a request to the server and the server sends back a response. HTTP enables this communication by establishing a TCP connection between the client and the server.
Ref image below.
Notice the connectd to and the port number 80 part. This indicates that the connection is established over TCP.
HTTP is a stateless protocol. This means that each request is independent of the previous request.
Limitations of HTTP
Every interaction between the client and the server needs a new request over a new TCP connection. This is inefficient.
HTTP communication is one way only. The server cannot send data to the client without the client requesting it.
What are web sockets ?
Web sockets is a communicatin protocolo than enabled bi-directional communication between the client and the server. Web sockets achieve this by establishing a persistent long-lived TCP connection.
Once the connection is established, both the client and server can send data to each other without the need for a new request.
How does web sockets work ?
Web sockets in function through three steps.
Websocket handshake
The client initiates the connection by sending an HTTP GET request with specific headers, including Upgrade: websocket and Connection: Upgrade.
The server, if it supports WebSockets, responds with an HTTP 101 Switching Protocols response, also containing the Upgrade and Connection headers, along with a Sec-WebSocket-Accept header for security.
This handshake successfully "upgrades" the HTTP connection to a WebSocket connection.
You can easily see this happening in network tab. Checkout the image below showing a popular chat application whatsapp establishing a web socket connection.
Data transfer
After the handshake, communication happens over the established TCP connection using WebSocket frames.
These frames contain a payload (the actual data) and some metadata about the data type (text, binary, etc.).
Since it's a persistent connection, both the client and server can send these frames whenever they have data to transmit.
A WebSocket frame carries a header with control info (like data type and length) and an optional mask, followed by the actual data. Think of it as a lightweight envelope for your real-time messages.
Web socket close
Either the client or the server can initiate the closing of the WebSocket connection through a closing handshake.
This involves sending a special close frame and acknowledging the received close frame from the other party.
Working with web sockets in JavaScript
Here's a quick example of how to use web sockets in JavaScript.
Use load balancers with sticky sessions + Redis Pub/Sub for broadcasts
Proxy/firewall issues
Fall back to HTTP long-polling if blocked; always use wss://
No multiplexing
Implement app-level channel IDs for multiple streams
Stateful connections
Track clients in a shared DB; handle orphaned connections
Limited browser control
Use workarounds (e.g., app-level pings, binary encoding)
No binary compression
Manually compress data (e.g., zlib for Node.js)
Security risks (DoS, CSWSH)
Validate Origin, rate-limit, sanitize messages
Unpredictable performance
Monitor latency; fall back to HTTP in poor conditions
No caching
Cache critical data separately via HTTP/CDN
Poor debugging tools
Use wscat, DevTools, or specialized WebSocket testers
Scaling web sockets for million connections
Here are some of the things which big companies do to scale web sockets for millions of users.
Distribute Connections Using Sticky Load Balancing
To avoid overloading a single server, connections must be spread across multiple machines. Sticky sessions (session affinity) ensure that a userâs WebSocket connection consistently routes to the same backend server, preventing reconnection delays. Load balancers like NGINX, HAProxy, or AWS ALB handle this by hashing the clientâs IP or session token. Without sticky sessions, reconnections could bounce users between servers, breaking real-time sync.
Optimize Payloads with Binary Protocols (Protobuf/MessagePack)
JSON is human-readable but bloated. Binary protocols like Protocol Buffers (protobuf) or MessagePack reduce payload size by 40-60%, saving bandwidth and CPU. For example:
If WebSockets fail, fall back to HTTP long-polling (used by WhatsApp after ~2 minutes of inactivity).
Deploy Globally with Edge POPs to Reduce Latency
A user in Mumbai shouldnât connect to a server in New York. Edge computing (Cloudflare, AWS Global Accelerator) places WebSocket servers in regional data centers:
Users connect to the nearest edge location (e.g., ws-mumbai.example.com).
Reduces latency from 200ms â 20ms.
Enables compliance with data sovereignty laws (GDPR, etc.).
Monitor & Auto-Scale Based on Real-Time Metrics
Traffic spikes (e.g., New Yearâs Eve) can overwhelm servers. Solutions:
Auto-scaling (Kubernetes, AWS ECS) spins up servers when CPU/memory exceeds 70%.