Build real-time applications. Covers WebSocket architecture, SSE, long polling, real-time database patterns, connection scaling, and choosing the right real-time protocol.
WebSocket connections enable persistent, bidirectional communication between clients and servers. This pattern is essential for applications requiring real-time updates, such as chat systems, live dashboards, collaborative tools, or gaming interfaces. Unlike traditional HTTP requests, WebSockets maintain an open connection that allows either end to send data at any time without initiating a new request.
A WebSocket connection begins with an HTTP upgrade request from the client to the server. The handshake uses standard HTTP headers and requires specific values in the Connection and Upgrade fields:
GET /websocket/endpoint HTTP/1.1
Host: example.com
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
The server responds with a 101 Switching Protocols status and matching headers:
HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
After this exchange, the connection switches to binary or text frames using the WebSocket protocol. The client can send PING frames to keep the connection alive and receive PONG responses from the server.
A WebSocket session must handle various states and transitions. When a client connects, it receives a unique identifier (typically a UUID) that persists for the duration of the session. This ID is often passed in a header or stored in session state:
GET /websocket/endpoint HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
If a client disconnects, the server should track this event and potentially notify other connected clients. Reconnection logic must be handled by the client, as the server does not automatically reconnect disconnected peers.
WebSocket messages are either text or binary frames. Text frames carry UTF-8 encoded strings and are used for structured data like JSON. Binary frames carry raw bytes and are ideal for media or performance-sensitive payloads.
A server may receive messages in any order and must process them accordingly. For example, a chat application might handle incoming messages as:
{
"type": "message",
"content": "Hello world",
"timestamp": "2023-05-15T14:30:00Z",
"sender": "user-123"
}
Messages should be validated for structure and content before processing. If a message is malformed, the server can close the connection with a close code indicating the reason:
CLOSE 1002
WebSockets lack built-in keep-alive mechanisms. Applications must implement their own heartbeat logic to detect dead connections. Clients send periodic PING frames and expect PONG responses from the server.
If a server does not respond to a PING within a configured timeout, it should close the connection with code 1002 (protocol error). Servers can also initiate timeouts based on inactivity:
PING {"type": "heartbeat"}
PONG {"type": "heartbeat_response"}
A WebSocket connection can fail silently or abruptly. Common failure modes include network interruptions, server crashes, or protocol violations. When a connection closes, it provides a numeric close code and optional reason string.
The most common codes are:
If the client does not reconnect automatically, it must implement retry logic with exponential backoff. Reconnection attempts should include authentication tokens and resynchronization data to restore state.
WebSocket connections do not guarantee message delivery or ordering. Applications must implement their own mechanisms for reliability. For example, a chat system might include sequence numbers in messages:
{
"type": "message",
"content": "Hello world",
"sequence": 42,
"timestamp": "2023-05-15T14:30:00Z"
}
The client can track expected sequence numbers and request retransmissions for missing messages. Alternatively, applications can implement acknowledgment mechanisms using a separate channel or message IDs.
Authentication for WebSocket connections typically occurs during the handshake. The server validates credentials provided in headers or cookies. Common approaches include:
Authorization headerCookie headerIf authentication fails, the server should close the connection immediately with a 401 status code in the upgrade response.
WebSocket servers must handle concurrent connections efficiently. Each connection consumes memory and CPU resources. Applications may use load balancers that support sticky sessions to ensure clients connect to the same backend instance.
For horizontal scaling, stateless approaches are preferred. Server instances should avoid storing client session data in memory unless using a shared cache like Redis or Memcached.
WebSocket connections should expose metrics such as:
These can be collected using standard monitoring tools like Prometheus, Grafana, or application performance management (APM) platforms. The server must track connection duration, message counts, and error frequencies.
Several issues can silently break WebSocket functionality:
A minimal WebSocket server configuration includes:
websocket:
max_message_size: 1048576
ping_interval: 30
timeout: 60
allowed_origins:
- https://example.com
- https://app.example.com
The max_message_size controls the largest message that can be received. Messages larger than this limit should cause connection closure with code 1008.
High-throughput WebSocket applications must consider:
For systems processing thousands of concurrent connections, using a language with lightweight threading (like Go) or event loops (Node.js) becomes crucial.
This page was rewritten on 15 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy