WebSockets

Updated June 6, 2026
M
Magic Magnets Team
9 min read

Imagine trying to have a phone conversation using a system where only one person can call the other, and after each sentence you have to hang up and wait to be called back. That's roughly what HTTP-based communication feels like for real-time apps. WebSockets fix this.

WebSockets give you a persistent, full-duplex connection between client and server. Both sides can send messages at any time, independently, without waiting for the other to ask. It's a real conversation, not a series of phone tags.

The WebSocket Handshake

Here's something that surprises most people: WebSocket connections start as HTTP.

The client sends a regular HTTP request with a special header:

GET /chat HTTP/1.1 Host: chat.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13

If the server supports WebSockets, it responds with:

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

That 101 Switching Protocols is the upgrade moment. The TCP connection that carried the HTTP request is now handed over to the WebSocket protocol and it stays open. From this point on, both client and server communicate using lightweight WebSocket frames, not HTTP.

algobase.dev
A WebSocket connection starts as a standard HTTP request with special headers: "Upgrade: websocket" and "Connection: Upgrade." The server responds with 101 Switching Protocols, and the same TCP connection that carried the HTTP request is handed over to the WebSocket protocol. From this point on, both sides communicate using lightweight WebSocket frames — no HTTP headers per message, no reconnect overhead, no waiting for the other side to ask before sending. The handshake happens once. Everything after that is low-overhead framing over the persistent channel.
1 / 1

WebSocket handshake — HTTP upgrade to persistent full-duplex connection

This upgrade handshake is clever for a few reasons. It means WebSockets work on port 80 and 443 (the same ports as HTTP and HTTPS), so they pass through most firewalls and proxies without special configuration.

Quiz Time

What HTTP status code signals that a WebSocket upgrade was accepted, and what does it mean?

Full-Duplex: Both Sides Talk Freely

With WebSockets, the server doesn't need to wait for the client to ask before sending data. When something happens, a new chat message, a stock price change, a collaborative edit, the server pushes it immediately.

The client can send messages whenever it wants too.

This is fundamentally different from long polling, where:

  • The client always initiates
  • The server can only respond (never push first without a waiting request)
  • There's connection overhead on every reconnect

With WebSockets, you pay the handshake cost once. Everything after that is low-overhead framing.

Use Cases That Actually Need WebSockets

Not every feature needs WebSockets. But when they're the right tool, they're really the right tool.

Real-Time Chat

Slack, Discord, and WhatsApp Web all need sub-second message delivery. Long polling's reconnect overhead would noticeably degrade the experience at scale.

Live Collaboration

Figma is a great example. When you move an object, every collaborator sees it move in real time. That requires the server to push your cursor position and edits to dozens of other clients simultaneously, continuously.

Trading Dashboards and Live Data Feeds

Financial platforms like Robinhood and Bloomberg push real-time price quotes, order book updates, and trade confirmations. Latency matters here — a stale price quote for even a few seconds can mean bad trades.

Multiplayer Games

Game state (player positions, scores, events) must be synchronized across clients in near real-time.

Live Dashboards

DevOps monitoring tools, real-time analytics boards, live delivery tracking, anything where data changes faster than a reasonable polling interval.

Scaling WebSockets: The Hard Part

Here's where things get interesting, and where WebSockets differ most from stateless HTTP.

HTTP servers are naturally stateless. Any server can handle any request. You can add or remove servers and a load balancer distributes traffic cleanly.

WebSockets are stateful. A connection lives on a specific server. That server holds the state of that connection — the user's session, subscriptions, any in-memory data. If the user's next message hits a different server, it doesn't have that context.

Sticky Sessions

The simplest solution is sticky sessions (also called session affinity). The load balancer looks at a cookie or IP address and ensures all requests from a given client always go to the same server.

This works, but it's fragile. If that server goes down, all its connections are lost. And it makes it harder to rebalance traffic across servers.

Connection Brokers / Message Buses

A more robust approach: use a shared pub/sub layer (like Redis Pub/Sub or Kafka) so that all WebSocket servers can communicate.

When a message needs to go to user A, the server handling it publishes to Redis. Every WebSocket server subscribes to that channel. The server that holds user A's connection picks it up and delivers it.

algobase.dev
WebSocket connections are stateful — Client A is tied to Server A. When Client A sends a message intended for Client B, Server A receives it but cannot deliver it directly because Client B is connected to Server B. The solution is a shared message bus (Redis Pub/Sub is the standard choice). Server A publishes the message to a Redis channel. Both Server A and Server B subscribe to that channel. Server B receives the message and delivers it to Client B. This pattern is how Slack, Discord, and most large-scale real-time systems work — each user's connection lives on one server, but a shared broker makes it possible to reach any user from any server.
1 / 1

Scaling WebSockets with Redis Pub/Sub — messages route between servers

This is how Slack, Discord, and most large-scale WebSocket systems actually work. Your connection might be on Server 3, but a message from someone on Server 7's connection reaches you because both servers share a message bus.

Quiz Time

Why do WebSockets require sticky sessions (or a message bus) when scaled horizontally?

Horizontal Scaling with a Gateway

Many modern systems put a dedicated WebSocket gateway in front of the application servers. The gateway handles connection state, and the application servers remain stateless. This is the pattern used by services like Pusher and Ably.

WebSockets vs the Alternatives

WebSocketsLong PollingServer-Sent Events
DirectionFull-duplexClient-initiatedServer-to-client only
ConnectionPersistentReconnects per eventPersistent (one-way)
ProtocolWS/WSSHTTPHTTP
Browser supportExcellentExcellentGood (not IE)
Load balancingHarder (sticky sessions)Easy (stateless)Medium

Server-Sent Events (SSE) are worth knowing about too. They're a simpler alternative when you only need server-to-client push (no client-to-server streaming). SSE works over plain HTTP/2, handles reconnection automatically, and avoids the sticky session problem. Good for live notifications and AI-streaming responses.

Quiz Time

When should you choose Server-Sent Events (SSE) over WebSockets?

Real-World Examples

  • Slack: WebSockets for message delivery, presence updates (online/away status), and typing indicators
  • Figma: WebSockets for real-time collaborative editing and cursor positions
  • Robinhood / Coinbase: WebSockets for live price feeds and portfolio updates
  • Google Docs: Operational transforms over WebSockets for collaborative editing
  • GitHub: WebSockets for live notification feeds and pull request activity

Summary

WebSockets give you a persistent, full-duplex channel between client and server, established via an HTTP Upgrade handshake and maintained as a long-lived TCP connection. They're the right choice for real-time chat, live collaboration, trading feeds, and multiplayer games. The main scaling challenge is their statefulness: unlike HTTP, WebSocket connections are tied to specific servers, which requires sticky sessions or a shared message bus to scale horizontally. At large scale, systems like Slack and Discord solve this with a pub/sub layer (typically Redis) that allows any server to relay messages to any connected client.

How helpful was this content?

Comments

0/2000

Sign in to join the discussion

Saved on this device only

Sign in to sync progress across devices