Anatomy of a Request
what happens before your code runsBefore a single line of your handler executes, four things had to happen: the name resolved to an address, a TCP connection opened, a TLS session negotiated, and the HTTP request crossed the wire. Each is a round trip or more. On a fresh connection to a distant server, you can spend 300ms on setup before the server even sees the request.
Knowing where that time goes is the point. Most front-end latency wins come from cutting round trips out of this path, not from faster application code.
Browser Server
â â
â 1. DNS lookup example.com âââļ 93.184.x.x â ~20â120ms
â (may be cached; skip if warm) â (first time)
â â
â 2. TCP handshake SYN ââļ ââ SYN-ACK ACK ââļ â 1 round trip
â â
â 3. TLS handshake ClientHello ââļ ââ ... ââļ â 1 RT (TLS 1.3)
â â 2 RT (TLS 1.2)
â 4. HTTP request GET / âââââââââââââââââââââââââļ â
â âââââââââââââââââââââââââ 200 OK â TTFB
â â
âŧ first byte arrives âŧ
TTFB = time to first byte = setup + one request/response round trip.
DNS: Names to Addresses
the internet's phone book, and its routing leverDNS turns example.com into an IP. A recursive resolver (usually your ISP's or something like 8.8.8.8) does the legwork, walking from the root to the authoritative nameserver that actually owns the record, then caching the answer for its TTL. Most lookups never leave the resolver's cache.
DNS is also a load-balancing and routing tool. Return multiple A records and clients spread across them. Return different answers based on the resolver's location â GeoDNS â and you send each user to their nearest region.
A long TTL means fewer lookups and faster page loads, but slow propagation: change a record and old answers linger until caches expire. A short TTL flips it â quick failover, more lookup traffic.
This is why DNS is a weak failover mechanism. You can't yank traffic off a dead server faster than clients honor the TTL, and some ignore it entirely.
The authoritative server picks an answer based on where the resolver sits, sending users to a nearby region. Cheap global routing with no extra hop.
The catch: it sees the resolver, not the user. Someone on a distant public resolver gets routed by the resolver's location, not their own. For precise routing, anycast beats it (Discovery).
TCP vs UDP
reliability you pay for, or speed you don'tTCP gives you a reliable, ordered byte stream: it handshakes to open a connection, acknowledges every segment, retransmits losses, and slows down under congestion. All of that costs round trips and head-of-line blocking â a lost packet stalls everything behind it until it's resent.
UDP gives you none of it. Fire a datagram and hope. No handshake, no ordering, no retransmit. That's a feature when late data is useless: in a video call, a dropped frame should be skipped, not resent stale.
| Property | TCP | UDP |
|---|---|---|
| Connection | Handshake first (1 RT) | None â just send |
| Delivery | Guaranteed, retransmitted | Best-effort, may drop |
| Ordering | In order | No guarantee |
| Head-of-line blocking | Yes â a loss stalls the stream | No â packets independent |
| Overhead | Higher (state, acks, congestion control) | Minimal |
| Fits | Web, APIs, databases, anything correctness-first | Video, voice, gaming, DNS, QUIC |
HTTP Versions
each one fixed the last one's bottleneckThe through-line across HTTP versions is a war on round trips and head-of-line blocking. Each version removed a place where requests had to wait in line.
HTTP/1.1 one request at a time per connection. Response N blocks N+1.
Workaround: open 6 parallel connections and keep them alive.
âŧ still blocks: slow response holds up its whole connection
HTTP/2 multiplexing â many streams over ONE connection, interleaved.
Header compression. Server push (mostly unused).
âŧ but all streams share one TCP stream: a lost packet
stalls every stream (TCP-level head-of-line blocking)
HTTP/3 runs on QUIC (UDP). Streams are independent, so one lost
packet stalls only its own stream. Faster handshake
(crypto + transport in one). 0-RTT resumption.
| Version | Transport | Fixed | Still limited by |
|---|---|---|---|
| HTTP/1.1 | TCP | Keep-alive, pipelining | One in-flight response per connection |
| HTTP/2 | TCP | Multiplexing, header compression | TCP head-of-line blocking across streams |
| HTTP/3 | QUIC / UDP | Independent streams, faster handshake, 0-RTT | Newer, some middleboxes block UDP |
TLS: The Encryption Handshake
a round trip for privacy, and where to pay itTLS encrypts the connection and proves the server's identity via a certificate. The cost is the handshake: one extra round trip in TLS 1.3, two in the older TLS 1.2. On a cold connection that's added latency on top of TCP setup.
Two mitigations matter. Session resumption lets a returning client skip the full handshake with a cached key â even 0-RTT, sending data on the first packet. And TLS termination at the load balancer means the expensive crypto happens once at the edge, not on every app server.
Public internet Your network (trusted)
Client ââââââââââââââââââââââââļ Load Balancer âââââââââââââââļ App servers
encrypted (TLS) â decrypts here plain HTTP
â (TLS termination) (or re-encrypted
âŧ for zero-trust:
certs, crypto centralized mTLS everywhere)
Terminating TLS at the edge simplifies certificate management and offloads CPU, but it means traffic inside your network is plaintext by default. Whether that's acceptable depends on your trust model â a zero-trust design re-encrypts internally with mTLS (Security Basics).
CDNs and Edge Delivery
move the bytes closer to the userA CDN is a fleet of edge servers (PoPs) spread across the globe, each caching copies of your content. The user hits the nearest edge instead of your origin, cutting latency and offloading traffic. For static and cacheable content, this is the single biggest delivery win available â and the dominant cost line for anything media-heavy (Video Streaming).
Origin pull: the edge fetches from your origin on the first miss, then caches. Lazy, self-managing, the default.
Push: you upload content to the CDN ahead of demand. More control, used for large predictable assets like video segments.
The edge keys on URL (plus chosen headers). Change content at the same URL and edges keep serving the old copy until the TTL expires or you purge it.
The standard fix is versioned URLs â app.a1b2c3.js â so new content gets a new key and old caches simply age out.
Put on a CDN what's static or reusable across users: images, video, CSS/JS, fonts, and cacheable API responses. Keep off it anything per-user or sensitive unless you gate access. For private content, signed URLs grant time-limited access to a specific object without making it public â the same mechanism that lets clients pull a paywalled video segment straight from the edge.
Quick Reference
the request path on one card| Step | What it costs | How to cut it |
|---|---|---|
| DNS lookup | ~20â120ms cold, ~0 warm | Caching + TTL tuning; keep it for coarse routing |
| TCP handshake | 1 round trip | Keep-alive, connection pooling |
| TLS handshake | 1 RT (1.3), 2 RT (1.2) | Session resumption, 0-RTT, edge termination |
| Request / response | 1 RT to origin (TTFB) | CDN edge, HTTP/2+3 multiplexing |
| TCP | UDP |
|---|---|
| Reliable, ordered, congestion-controlled | Best-effort, unordered, minimal |
| Web, APIs, DBs â correctness first | Video, voice, gaming, DNS, QUIC/HTTP3 |