How the Internet Works: DNS, TCP, TLS and HTTP
Everything that happens between a user typing a URL and bytes arriving - and why each hop is a place where latency and failure live.
Covers: DNS resolution, TCP vs UDP, the TLS handshake, HTTP/1.1 vs HTTP/2 vs HTTP/3, connection reuse, head-of-line blocking
“What happens when you type a URL into a browser?” is the most-asked warm-up question in the industry, and it is not filler. Every answer you will give later - CDNs, load balancers, connection pooling, keep-alives, why cross-region calls hurt - depends on understanding this sequence.
The full journey of one HTTPS request
Tap each stage. The recurring theme: almost all of the time is spent on round trips, not on computation.
Flow
- BrowserDNS resolver(resolve)
- DNS resolverTCP handshake(IP)
- TCP handshakeTLS handshake
- TLS handshakeCDN edge
- CDN edgeOrigin(miss only)
30-second answer
The browser checks its caches, resolves the hostname to an IP via DNS, opens a TCP connection with a three-way handshake, negotiates TLS, sends an HTTP request, and receives a response - usually from a CDN edge rather than the origin. The browser then parses the HTML and repeats the process for every referenced asset. The whole sequence is dominated by round trips, which is why caching, connection reuse and edge termination matter more than server speed.
1 · Browser-local checks
HSTS list (force HTTPS), then in-memory and OS DNS caches, then the existing connection pool. A warm connection to a resolved host skips steps 2–4 entirely.2 · DNS resolution
Recursive resolver → root → TLD → authoritative nameserver, unless a cached answer exists. Returns one or more A/AAAA records. Modern setups return a CDN's anycast address rather than your origin's IP.3 · TCP three-way handshake
SYN → SYN-ACK → ACK. One full RTT. The client may start sending after the third packet, so effectively one RTT of setup cost.4 · TLS handshake
ClientHello with supported ciphers → server certificate and key share → session keys derived. TLS 1.3: 1 RTT, or 0-RTT on resumption. The client validates the certificate chain to a trusted root and checks the hostname.5 · HTTP request/response
The request travels to the nearest CDN PoP. Cache hit → served immediately. Miss → forwarded to origin, where a load balancer picks an application server, which may consult a cache and a database.6 · Render and repeat
Browser parses HTML, discovers CSS/JS/images, and issues more requests - reusing the connection under HTTP/2 or HTTP/3, or opening up to six parallel connections per origin under HTTP/1.1.
DNS is also a systems tool, not just a lookup
| DNS technique | Used for | Caveat |
|---|---|---|
| Round-robin A records | Crude load distribution across IPs | No health awareness - clients keep hitting a dead IP until TTL expires |
| Low TTL (30–60 s) | Fast failover between regions | More resolver traffic; some resolvers ignore very low TTLs |
| GeoDNS / latency-based routing | Send users to their nearest region | Resolver location ≠ user location when public resolvers are used |
| Anycast IP | One address announced from many PoPs; BGP picks the nearest | Requires network-level support; the standard for CDNs |
| CNAME to a provider | Delegating traffic management to a CDN or LB | Adds a lookup hop; cannot be used at a zone apex without provider tricks |
Say these points
- Cache check → DNS → TCP → TLS → HTTP → render, and every asset repeats the tail of it.
- Cold HTTPS to a far origin ≈ 4 RTTs before the first byte.
- TLS 1.3 is 1 RTT (0 on resumption); TLS 1.2 is 2.
- DNS TTL is a failover control, not just a caching detail.
Avoid these mistakes
- Reciting steps without attaching latency or failure behaviour.
- Forgetting that the browser's connection pool short-circuits most of the sequence.
- Treating DNS round-robin as real load balancing - it has no health checks.
- Assuming a user's DNS resolver is geographically near the user.
Expect these follow-ups
- How would you fail traffic over to another region, and how fast can it possibly be?
- Why does a page with 50 small assets feel slow even on a fast connection?
- What breaks if you set your DNS TTL to 5 seconds?
30-second answer
TCP gives ordered, reliable, congestion-controlled delivery at the cost of handshakes, retransmission delay and head-of-line blocking. UDP gives you a fire-and-forget datagram with none of those guarantees and none of that overhead. Use TCP when correctness and completeness matter - APIs, page loads, file transfer. Use UDP when timeliness beats completeness - live video, voice, gaming, DNS, metrics. QUIC is the interesting middle: it runs reliability and congestion control over UDP in user space, so it gets TCP's guarantees per stream without TCP's cross-stream head-of-line blocking.
| TCP | UDP | |
|---|---|---|
| Connection | Handshake required (1 RTT) | None - send immediately |
| Delivery | Guaranteed, retransmitted | Best effort, may be lost |
| Ordering | Strictly ordered | Arbitrary |
| Congestion control | Built in | Your problem |
| Header overhead | 20+ bytes | 8 bytes |
| Head-of-line blocking | Yes - one lost packet stalls the stream | No |
| Typical uses | HTTP, database protocols, SSH, file transfer | DNS, live video/voice, gaming, metrics, QUIC |
The decision rule
Head-of-line blocking, the problem that produced HTTP/3
HTTP/1.1 could send only one request at a time per connection, so browsers opened six connections per origin. HTTP/2 fixed that at the application layer with multiplexed streams over one TCP connection - but TCP itself still delivers bytes strictly in order. One lost packet stalls every multiplexed stream, because TCP will not hand over later bytes until the gap is filled. Under packet loss, HTTP/2 can be worse than HTTP/1.1.
QUIC solves this by moving reliability up into the protocol itself, over UDP. Each stream is independently ordered, so a lost packet stalls only its own stream. It also merges the transport and crypto handshakes into a single round trip, and identifies connections by an ID rather than a four-tuple - so a phone switching from Wi-Fi to cellular keeps its connection instead of reconnecting.
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Transport | TCP | TCP | QUIC over UDP |
| Concurrency | ~6 connections/origin | Multiplexed streams | Multiplexed streams |
| HoL blocking | At the request level | At the TCP level | Per stream only |
| Header compression | None | HPACK | QPACK |
| Setup RTTs (with TLS) | 2–3 | 2–3 | 1, or 0 on resumption |
| Connection migration | No | No | Yes (connection ID) |
| Server push | No | Yes (largely abandoned) | Effectively no |
Say these points
- TCP = reliable, ordered, congestion-controlled, with handshake and HoL cost.
- UDP = no guarantees, no setup - right whenever a late packet is worthless.
- HTTP/2 multiplexes at the app layer but still suffers TCP-level head-of-line blocking.
- QUIC gives per-stream ordering, 1-RTT setup and connection migration over UDP.
Avoid these mistakes
- Saying 'UDP is faster' without qualifying that it is faster because it does less.
- Claiming HTTP/2 eliminates head-of-line blocking entirely.
- Forgetting that HTTP/3 needs a fallback path where UDP is blocked.
- Choosing UDP for something that genuinely needs completeness, then rebuilding TCP badly on top.
Expect these follow-ups
- You are designing a multiplayer game's netcode. Which protocol, and what do you build on top?
- Why did HTTP/2 server push get deprecated in practice?
- How does connection migration help a mobile app specifically?
30-second answer
An L4 load balancer routes on IP and port without reading the payload - it is fast, protocol-agnostic and cheap, but it cannot make decisions based on the request. An L7 load balancer terminates the connection and parses HTTP, so it can route by path, host or header, retry idempotent requests, do TLS termination, compression, rate limiting and sticky sessions. Use L4 for raw throughput and non-HTTP protocols; use L7 whenever routing decisions depend on the content of the request, which for a modern web system is almost always.
| L4 (transport) | L7 (application) | |
|---|---|---|
| Sees | IP, port, TCP/UDP flags | Full HTTP: method, path, headers, cookies |
| Can route by | Source/dest address, port | Host, path, header, cookie, method |
| TLS | Passes through encrypted (or does TCP passthrough) | Terminates and re-encrypts |
| Overhead | Very low; near line rate | Higher - parses and buffers |
| Retries | No (it cannot know what the request was) | Yes, for idempotent requests |
| Health checks | TCP connect succeeds | HTTP 200 on /healthz with body checks |
| Typical use | Databases, gRPC passthrough, extreme throughput | Public web and API traffic |
What L7 buys you concretely
- Path-based routing -
/api/*to the API service,/static/*to object storage,/wsto the WebSocket tier. - Canary and blue-green - send 1% of traffic to the new version by header or weight.
- TLS termination - one place to manage certificates instead of on every application server.
- Smart health checks - a server whose database pool is exhausted returns 503 on
/healthzand is removed, even though its TCP port is still open. L4 would keep sending it traffic. - Retries and outlier ejection - automatically retry a failed idempotent GET on a different backend.
- Rate limiting and WAF - reject abusive traffic before it reaches your code.
Where each sits in a real stack
L4 and L7 together
Large deployments use both: an L4 layer for raw distribution and DDoS absorption, then L7 proxies for routing intelligence.
Flow
- ClientsL4 balancer
- L4 balancerL7 proxies
- L7 proxiesAPI service(/api)
- L7 proxiesWebSocket tier(/ws)
- L7 proxiesObject storage(/static)
Say these points
- L4 routes on IP/port and is fast; L7 parses HTTP and can route on content.
- L7 health checks distinguish 'port open' from 'actually able to serve'.
- L7 enables path routing, canaries, TLS termination, retries and rate limiting.
- Big stacks use L4 in front of L7: throughput first, intelligence second.
Avoid these mistakes
- Relying on TCP health checks and leaving a deadlocked server in rotation.
- Using sticky sessions instead of externalising state.
- Forgetting the load balancer itself needs redundancy across zones.
- Terminating TLS at L7 and then sending plaintext across an untrusted network.
Expect these follow-ups
- How do you drain connections from a backend during a deploy without dropping requests?
- Why is retrying a POST at the load balancer dangerous?
- How would you route 1% of traffic to a canary build safely?
Showing 3 of 3 questions for how-the-internet-works-dns-tcp-tls-http.
Check your understanding
4 questions · no sign-up, nothing stored
Hands-on challenge
Build it - this is what you talk about in a deep-dive round.
Trace and budget a real page load
Open your browser's network panel on any site and turn the waterfall into a latency budget.
Requirements
- Record DNS, TCP, TLS and TTFB timings for the document request.
- Count how many separate origins the page contacts and how many connections it opens.
- Identify which HTTP version each origin negotiated.
- Compute what fraction of total load time was round trips versus server processing.
- List the three changes that would most reduce the time to first contentful paint.
Stretch goals
- Repeat on a throttled 3G profile and note which bottleneck changes rank.
- Explain what a CDN would and would not fix in this specific waterfall.