WebSocket
Full-duplex, low-latency communication over one long-lived TCP connection.
📌 Key IdeaWebSocket upgrades from HTTP once, then keeps a persistent channel where both client and server can send messages at any time. It is ideal for real-time interactions, but reliability, ordering, retries, and reconnection semantics are application responsibilities.
Why It Matters
- Bidirectional by default — Server does not wait for client request to send updates.
- Low latency — No per-message HTTP handshake/header overhead.
- Efficient under frequent updates — Great for chat, feeds, collaboration, and live dashboards.
Visual
🌐 WebSocket flow (HTTP upgrade → full duplex)
1) Client sends HTTP Upgrade request 2) Server replies: 101 Switching Protocols 3) Same TCP connection stays open 4) Client <--> Server can push messages anytime ws:// (plain) wss:// (TLS encrypted)
Core idea: keep one connection open and push events instead of polling.
When to Use
- Live chat and presence updates.
- Real-time market ticks, scores, dashboards, and alert streams.
- Collaborative editing and multiplayer interactions.
- IoT command/control needing immediate push behavior.
When NOT to Use
- Pure request-response CRUD APIs where REST is enough.
- Public APIs that benefit from HTTP caching/proxies/inspectability.
- Workloads requiring strict built-in delivery guarantees without custom logic (consider Kafka/MQTT/gRPC stream + durability).
Code Variations
1️⃣ Spring WebSocket endpoint (minimal)java
@Component
public class PriceHandler extends TextWebSocketHandler {
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
session.sendMessage(new TextMessage("ack:" + message.getPayload()));
}
}Real apps add auth, subscriptions, heartbeat, and backpressure.
2️⃣ Browser client with reconnectjavascript
let ws;
function connect(delay = 250) {
ws = new WebSocket("wss://api.example.com/realtime");
ws.onopen = () => console.log("connected");
ws.onmessage = (e) => render(JSON.parse(e.data));
ws.onclose = () => setTimeout(() => connect(Math.min(delay * 2, 5000)), delay);
}
connect();Use exponential backoff and state replay on reconnect.
Pros & Cons
👍 Pros
- Low-latency real-time messaging.
- Single long-lived TCP channel reduces repetitive HTTP overhead.
- Strong browser support, including secure
wss://. - Event-driven model fits streaming UI updates.
👎 Cons
- Connection state management and scaling are harder than stateless HTTP.
- Reliability (ack, replay, ordering, dedupe) must be designed explicitly.
- Resource usage rises with many concurrent long-lived connections.
- No built-in persistence if process crashes.
WebSocket vs alternatives
| Aspect | WebSocket | HTTP Polling / Long Polling | SSE |
|---|---|---|---|
| Direction | Full duplex (both ways) | Client-driven request/response | Server → client only |
| Latency | ✅ Low | ⚠ Higher (request cycle) | ✅ Low for server push |
| Network overhead | ✅ Low after upgrade | ❌ Repeated headers/connections | ✅ Lower than polling |
| Client → server push | ✅ Native | ✅ Via request | ❌ Not native |
| Operational complexity | ⚠ Stateful, scaling concerns | ✅ Simplest | ⚠ Medium |
Interview Q&A
Likely Follow-up Questions
- How do you authenticate and rotate tokens on long-lived sockets?
- How do you handle backpressure when client read speed is slow?
- When do you pick SSE over WebSocket?
Quick Cheat Sheet
ProtocolHTTP handshake then upgrade to persistent TCP channel.
Best forReal-time bidirectional interactions.
Must designReconnect, ack/replay, ordering, and backpressure.
SecurityUse
wss://, auth handshake, and message-level authorization.