Codetail

Article 1 of 15

The Request Journey

What really happens when you type a URL.

25 min read

The 13-step journey

You type https://google.com and hit Enter. In the next 100-500 milliseconds, your browser orchestrates a remarkable sequence of events across multiple systems: DNS resolvers, TCP connections, load balancers, application servers, databases, and back again.

Most developers use the web every day without knowing what's happening beneath the surface. That's fine until you need to debug a latency problem, design a system that handles millions of requests, or reason about where a failure is coming from. Step through the full journey below.

Request Flow VisualizerStart
🌐BrowserClient
📡DNSResolver
⚖️Load Bal.Router
🖥️App ServerLogic
🗄️DatabaseStorage

You type a URL and press Enter

0ms

The browser parses the URL (protocol, hostname, path). Before connecting, it needs to translate the hostname into an IP address, that's DNS's job.

1/13

Each hop in this chain has its own characteristics: latency, failure modes, caching behavior, and optimization opportunities. We'll cover each in depth.

Understanding this flow is the foundation of system design. Every scaling, caching, and reliability decision you'll ever make is rooted in knowing exactly what happens here.

Step 1: DNS Resolution

The internet routes traffic using IP addresses (like 142.250.80.46), not human-readable hostnames. DNS, the Domain Name System, is the phone book that translates one to the other. It's hierarchical, distributed, and heavily cached.

The caching hierarchy

Before a DNS query ever hits the network, multiple caches are consulted. Each layer has its own TTL (Time To Live), an expiry duration after which the cached answer is discarded and the lookup must be repeated. Step through a cold DNS lookup below:

DNS Resolution Chain
🌐
💻
🏢
🌍
📂
📋

TTL: the knob that controls freshness vs speed

TTL is set by whoever controls the domain. A short TTL (60 seconds) means changes propagate quickly, useful during a migration, but also means more DNS queries and higher latency for cold users. A long TTL (86400 seconds = 1 day) means faster repeat lookups but slow rollback if you need to change the IP.

TTLUse caseTrade-off
30-60sActive failover, migration windowMore DNS queries, higher cold latency
300s (5m)Most web services (sensible default)5-minute propagation window
3600s (1h)Stable infrastructure, rarely changingSlow to update; good for performance
86400s (1d)Static assets, CDN originsVery slow propagation, maximum caching

DNS as a routing tool

DNS isn't just a lookup service, it's a traffic distribution tool. Large services use GeoDNS to return different IP addresses based on where the query comes from, routing users to the nearest data center. Combined with Anycast (one IP, many physical locations), DNS becomes the first layer of global load balancing.

🌍

GeoDNS

Returns different IPs per region. EU users go to Frankfurt. US users go to Virginia. Reduces latency by 100ms+ for global services.

📡

Anycast

One IP address routed to the closest server via BGP. CDN providers use this for sub-10ms DNS resolution worldwide.

⚖️

DNS Load Balancing

Return multiple A records. The client picks one (usually the first). Rotation adds a layer of distribution before any LB.

🛡️

DNS Failover

Health checks trigger automatic DNS changes when servers go down. Recovery time equals TTL. Set short TTLs before planned maintenance.

Gotcha:"DNS propagation" is a myth for most changes. The delay you experience is just your old TTL expiring. Once the TTL is up, resolvers fetch fresh data immediately. Lowering your TTL before a migration to 60s means changes propagate in 60 seconds, not 48 hours.

Step 2: TCP Handshake & TLS

With an IP address in hand, the browser opens a TCP connection. TCP (Transmission Control Protocol) is the reliable transport layer, it guarantees that data arrives in order and without gaps, retransmitting any lost packets. Before a single byte of HTTP can be sent, TCP requires a 3-way handshake.

TCP 3-Way Handshake
Client
Server
1 RTT overhead

Why the handshake costs a round trip

Each round trip (client to server to client) takes time proportional to the physical distance. A request from New York to London travels ~5,500 km each way at roughly the speed of light through fiber, adding ~70ms of irreducible latency per round trip, regardless of server speed.

RouteDistanceMin RTT
NYC to NYC (same city)~50km~1ms
NYC to LA~4,500km~40ms
NYC to London~5,500km~70ms
NYC to Sydney~16,000km~180ms

TLS: adding encryption on top of TCP

HTTPS requires a TLS handshake after TCP. Switch the interactive above to TLSmode to see the additional round trips. TLS 1.2 added 2 RTTs on top of TCP's 1 RTT. TLS 1.3 (the current standard) reduced this to 1 RTT. Combined with TCP: 2 RTTs total before the first HTTP byte.

TLS 1.2
2 RTTs
Deprecated, still common on older infra
TLS 1.3
1 RTT
Current standard, 0-RTT resumption for repeat connections
HTTP/3 + QUIC
0 RTT*
QUIC replaces TCP, connection + TLS in one packet. *First visit: 1 RTT

Connection reuse: the real optimization

The handshake cost is amortized across many requests via keep-alive connections. HTTP/1.1 introduced persistent connections. HTTP/2 added multiplexing, multiple requests over a single TCP connection simultaneously, eliminating the per-request overhead entirely.

Performance tip:CDNs terminate TCP and TLS at edge locations close to users, then maintain long-lived "warm" connections back to your origin. A user in Sydney connecting to a CDN PoP 10ms away pays 20ms for TLS, not 360ms.

Steps 3-5: Load Balancer, Server & Database

Once the TCP connection is established, the browser sends an HTTP request. For any service at scale, this request doesn't go straight to an application server, it first hits a load balancer.

The load balancer

⚖️
Load Balancer
Reverse proxy that distributes requests across backend servers
Health checks
Continuously polls /health endpoints. Pulls unhealthy servers from rotation automatically.
Sticky sessions
Routes a user to the same server via cookie. Needed for stateful apps (avoid this when possible).
SSL termination
Decrypts HTTPS at the LB edge. Backend servers communicate over plain HTTP inside the VPC.

The application server

The app server receives the HTTP request and runs your code. A well-architected request handler follows a predictable sequence:

1
Authenticate Verify the JWT or session token. Reject invalid requests early, before doing any real work.
2
Authorize Check that this user is allowed to perform this action on this resource (RBAC/ABAC).
3
Cache check Query Redis or Memcached. A cache hit returns immediately, no DB query needed.
4
Business logic The actual work: validate input, compute results, call other services if needed.
5
Database query Only if the cache missed. Construct a parameterized query and send it over the connection pool.
6
Cache write Store the result in cache for subsequent requests. Set an appropriate TTL.
7
Serialize + respond JSON-serialize the response, set headers (Content-Type, Cache-Control, CORS), return 200.

The database: the slow step

The database is almost always the bottleneck. A query without an index performs a full table scan, O(n), reading every row to find matches. An indexed query is O(log n), orders of magnitude faster at scale. The difference between a 5ms query and a 5-second query is often a missing index.

🐌Full table scan
SELECT * FROM orders WHERE user_id = 42

O(n), reads every row. Fine at 1k rows, catastrophic at 10M.

Index lookup
SELECT * FROM orders WHERE user_id = 42
-- (with index on user_id)

O(log n), B-tree traversal. Fast at any scale.

N+1 problem:Fetching a list of 100 users then querying each user's orders separately equals 101 queries. Use a JOIN or batch fetch instead. N+1 queries are the most common database performance bug and often invisible until production load.

The Latency Budget

System design is fundamentally about latency budgets. Every hop in the request journey costs time. The question is: how much does each hop cost, and where can you recover it?

Toggle between the typical worst-case budget and what's achievable with modern infrastructure. The difference, 700ms vs 37ms, illustrates exactly why companies invest heavily in CDNs, caching, and database optimization.

Latency Budget Breakdown
📡DNS Lookup1-50ms
🔗TCP + TLS30-150ms
🌐Network transit1-100ms
⚖️Load balancer0-2ms
🖥️App server5-100ms
🗄️Database query1-500ms
📦Response transit1-100ms
Total round trip39-1002ms

Numbers every engineer should know

0msDNS cache hit (browser)
~1msRedis cache lookup
~5msSame-region DB query (indexed)
~70msNY to London (speed of light limit)
100msPerceptible delay threshold
300msNoticeable lag, users frustrated
1000msUsers leave for slower completion
~180msNY to Sydney (speed of light limit)

The speed-of-light latency floor is physical, no software optimization can beat it. This is why CDNs, edge computing, and regional replication exist. The goal is to serve from a location close enough that the physics works in your favor.