Back
🏗️

Cheatsheet — System Design

Protocols · Machine Coding · Performance · Storage · Security

🔌 Real-time Communication — Pick the Right Tool

WebSocket 🔁

Full-duplex, persistent TCP connection. Both sides can send anytime.

✅ Use when: Chat, multiplayer games, live trading, collaborative editing, live sports scores
❌ Avoid when: Client only reads data (no need for bidirectional), simple notifications
                    // Client
const ws = new WebSocket("wss://api.example.com/ws");
ws.onopen    = ()  => ws.send(JSON.stringify({ type:"join" }));
ws.onmessage = (e) => console.log(JSON.parse(e.data));
ws.onerror   = (e) => console.error(e);
ws.onclose   = ()  => console.log("disconnected");

// Need reconnect logic + heartbeat in production
                  

Server-Sent Events (SSE) 📡

One-way stream: server → client only. Runs over plain HTTP/1.1. Auto-reconnects natively.

✅ Use when: Live feed, notifications, dashboards, progress updates
⚠ Limit: Client-to-server still needs regular HTTP requests
                    // Server sends text/event-stream
// Client
const es = new EventSource("/api/stream");
es.onmessage = (e) => console.log(e.data);
es.onerror   = ()  => es.close();

// Named events
es.addEventListener("update", (e) => handle(e.data));

// Auto-reconnects with Last-Event-ID header 🎉
                  

Long Polling 🔄

Client sends request → server holds until data is ready → responds → client immediately re-requests.

⚠ Use when: Legacy browsers, no WebSocket support, infrequent updates
❌ Avoid for: High-frequency data — creates thundering herd, high server load
                    async function longPoll() {
  while (true) {
    try {
      const res = await fetch("/api/poll?since=" + lastId);
      const data = await res.json();
      process(data);
      lastId = data.lastId;
    } catch { await sleep(1000); }
  }
}
                  

Short Polling ⏱️

Client sends HTTP request every N seconds regardless of whether data changed.

⚠ Use when: Non-critical updates, very simple implementation needed
❌ Wasteful — hits server even when no new data
                    // Simple but inefficient
setInterval(async () => {
  const data = await fetch("/api/status").then(r => r.json());
  render(data);
}, 5000);
                  

Quick Comparison Table ⚡

Protocol Direction Latency Auto-reconnect Use case
WebSocketBidirectionalVery lowManualChat, gaming, collab
SSEServer→ClientLowNative ✅Notifications, feeds
Long PollingServer→ClientMediumManualLegacy support
Short PollingServer→ClientHighN/A (always on)Simple status checks
HTTP/2 PushServer→ClientLowManualProactive resource push
gRPC StreamingBidirectionalVery lowManualMicroservices, internal APIs

🌐 HTTP Protocols

HTTP/1.1 vs HTTP/2 vs HTTP/3

HTTP/1.1 1 request per TCP connection (with keep-alive: 6 parallel). HOL blocking.
HTTP/2 Multiplexing — many requests on 1 TCP. Header compression. Server push. Streams.
HTTP/3 QUIC (UDP-based). Faster handshake. No TCP HOL blocking. Better on lossy networks.
HTTP/2 is default for modern HTTPS sites. Fixes domain sharding anti-pattern from HTTP/1.

REST vs GraphQL vs gRPC

REST Resource-based URLs. Easy to cache. Over/under-fetching problem.
GraphQL Query exactly what you need. Single endpoint. Great for complex UIs. Harder to cache.
gRPC Binary (protobuf). Streaming. Typed. Best for internal microservices.
tRPC Type-safe APIs between TS client + server. No codegen.
Interview tip: Choose REST for simple CRUD, GraphQL when clients need flexible data shapes, gRPC for performance-critical internal services.

HTTP Caching

Cache-Control: no-store Never cache
Cache-Control: no-cache Cache but always revalidate
Cache-Control: max-age=3600 Cache for 1 hour
Cache-Control: immutable Never revalidate (use content hash in URL)
ETag Server sends hash; client sends If-None-Match; server returns 304 if unchanged
Last-Modified Same idea with timestamps

CDN & Edge

CDN caches static assets close to users. Edge functions run at CDN POPs.

  • Static assets: aggressive cache (1yr) with content hash in filename
  • HTML: short cache or no-cache (needs to stay fresh)
  • API: CDN caching for public data, bypass for private
  • Image CDN: resize/optimize on-the-fly (Cloudinary, Imgix, Next/Image)