WebSocket Protocol Explained: Full-Duplex Communication Over TCP

How WebSockets work — the upgrade handshake, frame format, when to use WebSockets vs SSE or polling, and scaling WebSocket connections in production.

websocketreal-timenetworkingfull-duplexprotocols

WebSocket Protocol

WebSocket is a communication protocol that provides full-duplex (bidirectional) communication channels over a single TCP connection, enabling real-time data exchange between client and server without the overhead of HTTP request-response cycles.

What It Really Means

HTTP is a request-response protocol — the client sends a request, the server responds, and the connection sits idle until the next request. This model works poorly for real-time applications like chat, live sports scores, multiplayer games, and collaborative editors where the server needs to push updates to the client immediately.

Before WebSockets, developers used workarounds: long polling (holding HTTP connections open waiting for data), server-sent events (one-way server-to-client stream), or Flash sockets. WebSockets replaced these hacks with a clean, standardized, bidirectional protocol.

A WebSocket connection starts as a normal HTTP request that is "upgraded" to WebSocket. After the upgrade, both sides can send messages at any time without HTTP headers, cookies, or other per-request overhead. A WebSocket frame has only 2-14 bytes of overhead compared to hundreds of bytes for HTTP headers.

How It Works in Practice

The Upgrade Handshake

After the Upgrade

Connection Lifecycle

  1. HTTP upgrade (one-time, one RTT)
  2. Bidirectional messaging (both sides send whenever they want)
  3. Heartbeat (PING/PONG frames detect dead connections)
  4. Close (either side sends a close frame)

Implementation

Server (Python with websockets library):

python

Client (JavaScript):

javascript

Trade-offs

WebSocket vs alternatives:

AspectWebSocketSSELong PollingHTTP/2 Push
DirectionBidirectionalServer-to-clientRequest-responseServer-to-client
ProtocolWebSocketHTTPHTTPHTTP/2
Browser supportExcellentGoodUniversalLimited
Auto-reconnectManualBuilt-inBuilt-inN/A
ScalabilityStatefulStatefulStatelessStateful
Proxy supportCan be trickyGoodExcellentGood

When to use WebSockets:

  • Chat applications (bidirectional, real-time)
  • Multiplayer games (low latency, bidirectional)
  • Collaborative editing (conflict resolution, real-time sync)
  • Financial trading (streaming price updates, order execution)

When NOT to use WebSockets:

  • One-way server-to-client updates (use SSE instead)
  • Infrequent updates (use polling or long polling)
  • Request-response APIs (use REST or gRPC)
  • When you need HTTP features (caching, redirects, content negotiation)

Scaling challenges:

  • Each WebSocket connection is stateful (server must maintain connection state)
  • Load balancers must support sticky sessions or WebSocket-aware routing
  • Horizontal scaling requires a pub/sub system (Redis Pub/Sub, Kafka) to broadcast across server instances
  • Memory: 10K connections at 10KB each = 100MB of server memory

Common Misconceptions

  • "WebSockets are always better than HTTP for real-time"Server-Sent Events are simpler, support auto-reconnect, and work better with HTTP infrastructure for one-way updates. Use WebSockets only when you need bidirectional communication.
  • "WebSocket connections are free to maintain" — Each connection uses memory, file descriptors, and CPU for heartbeat processing. At scale (100K+ connections), this becomes significant.
  • "WebSockets work through all proxies" — Some corporate proxies, older load balancers, and certain CDNs do not support WebSocket upgrades. Always implement a fallback (long polling).
  • "You do not need reconnection logic" — Connections drop due to network changes, idle timeouts, server deploys, and load balancer reconfiguration. Robust reconnection with exponential backoff is essential.

How This Appears in Interviews

  1. "Design a chat application" — WebSockets for real-time messaging. Discuss scaling with Redis Pub/Sub across server instances, message persistence, and reconnection handling.
  2. "Design a real-time notifications system" — Evaluate SSE vs WebSocket. Notifications are server-to-client only, so SSE might be simpler.
  3. "How do you scale WebSocket connections to 1 million users?" — Multiple server instances, Redis Pub/Sub for cross-server messaging, connection-aware load balancing, horizontal scaling.
  4. "What happens when the WebSocket server restarts?" — All connections drop. Clients must reconnect and re-subscribe. Discuss graceful shutdown and message replay.

Related Concepts

GO DEEPER

Learn from senior engineers in our 12-week cohort

Our Advanced System Design cohort covers this and 11 other deep-dive topics with live sessions, assignments, and expert feedback.