Fundamentals
Networking Essentials
TCP vs. UDP, DNS TTLs and failover, and what actually changed across HTTP/1.1, HTTP/2, and HTTP/3.
Almost nobody gets asked "explain TCP" directly in a system design interview — but the follow-up questions that decide a senior-level score ("why not just poll faster instead of using a WebSocket," "would you use UDP here") assume you already know the layer underneath the one you're designing at.
TCP vs. UDP
TCP guarantees ordered, reliable delivery — the receiver acknowledges each segment, and a lost one gets retransmitted — at the cost of that acknowledgment round trip. UDP sends packets with no delivery guarantee and no ordering, but with lower overhead and no retransmission delay. Almost every request/response API rides on TCP (via HTTP) because losing or reordering a response silently would be worse than the latency cost of guaranteeing delivery. UDP shows up where a stale, dropped packet is actively preferable to a delayed one — live video/audio, where a retransmitted frame arrives too late to be useful anyway, and real-time multiplayer game state, where the next update supersedes a dropped one regardless.
DNS, briefly
A domain name doesn't route anywhere by itself — DNS resolves it to an IP address through a chain of lookups (root servers → TLD servers → the domain's own authoritative nameserver), and clients cache the result for whatever TTL the DNS record specifies. This matters for system design specifically around failover: changing a DNS record to point traffic at a new server doesn't take effect everywhere instantly — clients holding a cached record keep hitting the old address until that TTL expires. A lower TTL means faster failover but more DNS query volume; this is a real, nameable trade-off if a design relies on DNS-based failover or traffic shifting.
HTTP, and what actually changed across its versions
- HTTP/1.1 — one request in flight per TCP connection at a time (without pipelining, which is rarely used in practice); browsers work around this by opening several connections per host.
- HTTP/2 — multiplexes multiple requests over a single TCP connection, removing the need for multiple connections per host, and adds header compression.
- HTTP/3 — runs over QUIC (built on UDP) instead of TCP specifically to avoid TCP's head-of-line blocking, where one lost packet stalls every multiplexed stream sharing that connection, not just the stream the lost packet belonged to.
HTTP caching
A Cache-Control response header tells a client — and any CDN sitting in
front of the origin — how long a response can be reused without asking
the server again; max-age=3600 means "good for an hour, don't even
check." ETag is the complementary mechanism for content that changes
unpredictably: the server tags a response with a hash of its content, and
a client can send that tag back on the next request (If-None-Match) —
if it still matches, the server replies 304 Not Modified with no body,
saving the transfer even though the check still happened. The
CDNs lesson's TTL-vs-purge
trade-off is this exact mechanism operating at the edge instead of the
browser.
Forward vs. reverse proxy
Both sit between a client and a server, but on opposite sides of "whose interest they represent." A forward proxy sits in front of clients — it's the client's agent, hiding the client's identity from the server it's requesting (a corporate outbound proxy, a VPN). A reverse proxy sits in front of servers — it's the server's agent, hiding the server's identity and topology from the client making the request. A load balancer is a reverse proxy that also distributes traffic across multiple backends; not every reverse proxy load-balances (some just terminate TLS or add a caching layer in front of a single origin), but every load balancer in this track is functioning as a reverse proxy.
gRPC
Where REST sends JSON over HTTP/1.1 for broad, human-debuggable compatibility, gRPC sends binary-encoded Protocol Buffers over HTTP/2 — smaller payloads, lower serialization cost, and native support for streaming, where a client and server can each keep sending messages over one open call instead of one request and one response. The trade-off: strictly less debuggable (no reading a raw request in a browser's dev tools) and less broadly compatible (browsers can't call it directly without a proxy layer). It shows up mostly for internal service-to-service calls, where both ends are code you control and the performance win matters more than human-readability — the API Design lesson's REST-vs-RPC framing is this exact choice.
WebSockets, long-polling, and SSE, explained
Three different ways to get server-initiated updates to a client, in increasing order of complexity:
- Long-polling — the client sends a request and the server holds it open, not responding, until it has new data or a timeout expires, then the client immediately opens another one. Simple, works over plain HTTP, but every held-open request still ties up a server connection.
- Server-sent events (SSE) — the server keeps one HTTP connection open and streams events down it as they happen. One-directional (server → client only), but simpler than a WebSocket when the client never needs to send anything back over that same connection.
- WebSocket — a single TCP connection upgraded from HTTP into a full-duplex channel; both sides can send at any time, with none of long-polling's repeated connection setup. This is what Chat System uses, specifically because messages flow in both directions and connection setup cost matters at that message volume.
Picking between these is a real, nameable trade-off, not "use WebSockets for anything real-time" — SSE is usually the better default when updates only flow one way (a live score, a progress bar), since it's simpler to operate and falls back cleanly through proxies that don't handle WebSocket upgrades well.
Where this connects back to the rest of the track
TCP handshake and connection setup cost is also the reason connection pooling exists at all — reusing an already-open TCP connection for the next request avoids paying that setup cost again, which is part of why HTTP/2's multiplexed single connection is a real efficiency win at scale, not just a protocol detail.