CS Fundamentals Trainer · Guides
What happens when you type a URL
DNS, TCP, TLS, HTTP and rendering in order, with a hand-built 29-byte DNS query, curl timings for each phase, and the standard ways to cut each round trip.
11 min read
"What happens when you type a URL into the browser and press Enter?" is one of the most common interview questions, because the honest answer touches almost every layer of the network and the browser. A good answer is an ordered story with a few real details in each step. This guide gives that story, and shows how to measure each step yourself.
1. The overview
Diagram: From typing a URL to pixels on the screen
The sections below take the steps in order.
2. Parsing the URL
https://www.example.com:443/docs/page?lang=en#intro has parts: scheme https, host www.example.com, port 443 (the default for https, so usually omitted), path /docs/page, query lang=en, and fragment intro. The fragment is never sent to the server; the browser uses it to scroll.
If you typed something that is not a URL, the browser sends it to a search engine instead. If you typed example.com, it adds https://. And before it makes any request it checks:
- Its own caches: a fresh copy of the page (from the
Cache-Controlheaders of an earlier visit) means no network request at all. - The HSTS list: if the site has told the browser "HTTPS only" (RFC 6797), an
http://address is upgraded tohttps://internally, before anything is sent.
3. DNS: from a name to an address
Computers connect to IP addresses, so the name must be resolved. The browser asks the operating system, which looks, in order, in:
- the browser's own DNS cache,
- the operating system cache and the
hostsfile, - the configured recursive resolver (your provider's, or a public one), which has its own cache.
If the resolver does not know, it asks on your behalf, walking down the hierarchy: a root server (which says where .com is run), a .com TLD server (which says which servers are authoritative for example.com), and finally the authoritative server for the domain, which gives the answer. Each answer carries a TTL, how many seconds anyone may cache it. That is why changing a DNS record can take as long as the old TTL to take effect everywhere.
A DNS query is tiny. I built one by hand for the A record (IPv4 address) of example.com: it is 29 bytes: a 12-byte header (id, flags with "recursion desired", one question), the name written as length-prefixed labels (7example3com0, 13 bytes), and 4 bytes for the record type and class. It normally goes over UDP port 53 in a single packet, and the answer comes back in one packet. (RFC 1035 describes the format [1].) Here is the builder (pick a language on the tabs; your choice is remembered):
import struct
def build_query(name, qtype=1, qid=0x1234):
header = struct.pack("!HHHHHH", qid, 0x0100, 1, 0, 0, 0) # id, flags (RD), 1 question
qname = b"".join(bytes([len(p)]) + p.encode() for p in name.split(".")) + b"\x00"
return header + qname + struct.pack("!HH", qtype, 1) # type A, class IN
print(len(build_query("example.com"))) # 29
func buildQuery(name string, qtype uint16, id uint16) []byte {
b := make([]byte, 12, 64)
binary.BigEndian.PutUint16(b[0:], id)
binary.BigEndian.PutUint16(b[2:], 0x0100) // recursion desired
binary.BigEndian.PutUint16(b[4:], 1) // one question
for _, label := range strings.Split(name, ".") {
b = append(b, byte(len(label)))
b = append(b, label...)
}
b = append(b, 0)
b = binary.BigEndian.AppendUint16(b, qtype)
b = binary.BigEndian.AppendUint16(b, 1) // class IN
return b
}
function buildQuery(name, qtype = 1, id = 0x1234) {
const parts = [];
const header = Buffer.alloc(12);
header.writeUInt16BE(id, 0);
header.writeUInt16BE(0x0100, 2); // recursion desired
header.writeUInt16BE(1, 4); // one question
parts.push(header);
for (const label of name.split(".")) {
parts.push(Buffer.from([label.length]), Buffer.from(label, "ascii"));
}
const tail = Buffer.alloc(5); // root label, type, class
tail.writeUInt16BE(qtype, 1);
tail.writeUInt16BE(1, 3);
parts.push(tail);
return Buffer.concat(parts);
}
static byte[] BuildQuery(string name, ushort qtype = 1, ushort id = 0x1234)
{
var ms = new MemoryStream();
void U16(ushort v) { ms.WriteByte((byte)(v >> 8)); ms.WriteByte((byte)v); }
U16(id); U16(0x0100); U16(1); U16(0); U16(0); U16(0);
foreach (var label in name.Split('.'))
{
ms.WriteByte((byte)label.Length);
ms.Write(Encoding.ASCII.GetBytes(label));
}
ms.WriteByte(0);
U16(qtype); U16(1);
return ms.ToArray();
}
Try it from the command line: dig +trace example.com shows the walk from the root down; dig example.com shows the TTL counting down on repeated queries.
Other record types you meet: AAAA (IPv6), CNAME (an alias to another name), MX (mail), TXT (free text, used for verification), NS (which servers are authoritative). Many large sites answer with a different address depending on where you are (a CDN or a global load balancer, see the load balancing guide). Modern setups also encrypt the query itself (DNS over HTTPS or TLS).
4. TCP: opening a connection
With an address, the browser opens a TCP connection to port 443 with the three-way handshake: the client sends SYN, the server answers SYN-ACK, the client sends ACK. That costs one round trip before data can flow. TCP then provides a reliable, ordered byte stream: numbering segments, acknowledging them, retransmitting what is lost, and slowing down when the network is congested (it starts with a small window and grows it, "slow start"). The browser typically opens several connections, or reuses an existing one (keep-alive). HTTP/3 replaces TCP with QUIC over UDP; see below.
5. TLS: making the connection private
For https, the client and server now run the TLS handshake: agree on keys, and the server proves its identity with a certificate. In TLS 1.3 this takes one more round trip. The TLS guide goes through it message by message. Along the way the client also uses ALPN to agree on the HTTP version (h2 or http/1.1).
6. The HTTP request and response
Now the browser sends the request:
GET /docs/page?lang=en HTTP/1.1
Host: www.example.com
Accept: text/html
Accept-Encoding: gzip, br
Cookie: session=…
(In HTTP/2 and HTTP/3 the same information is sent in a compact binary form, and many requests share one connection.) The server may be several machines behind a load balancer and a CDN; somewhere, application code runs, maybe reading a database or a cache, and returns:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Encoding: br
Cache-Control: max-age=300
Set-Cookie: …
<!doctype html>…
Other answers you should know: 301/308 (moved permanently, follow the Location header), 302/307 (temporarily elsewhere), 304 (not modified, use your cached copy), 404, 429 (slow down), 500/503 (server trouble). A redirect to a new URL repeats the steps for it: a new DNS lookup if the host differs, a new connection unless an existing one can be reused (HTTP/2 and HTTP/3 can reuse a connection for another name the certificate covers), and a new request. That is why redirect chains hurt page speed.
7. How long does each step take?
curl can report the time of each phase. Every value is cumulative, so subtract the previous one:
curl -sS -o /dev/null -w 'dns %{time_namelookup} tcp %{time_connect} tls %{time_appconnect} first byte %{time_starttransfer} total %{time_total}\n' https://example.com/
When I ran it against a server on my own machine, there was almost no network delay, so it showed tcp 0.0002 s, tls about 0.0035 s and first byte about 0.004 s: all the time was computation, none was waiting. On the real internet each of DNS, TCP, TLS and the request costs at least one round trip. With 100 ms between you and the server, a cold visit spends roughly: DNS 100 ms (if not cached) + TCP 100 ms + TLS 100 ms + request 100 ms, about 400 ms before the first byte, plus the time for the server to build the page. This explains the standard speed-ups:
| Technique | Step it removes or shortens |
|---|---|
DNS caching, dns-prefetch | DNS lookup |
| Keep-alive and HTTP/2 connection reuse | TCP and TLS for later requests |
| TLS 1.3, session resumption | a round trip of TLS |
| HTTP/3 (QUIC) | combines transport and TLS handshakes |
| CDN | shorter distance, fewer round trip milliseconds |
preconnect hint | opens TCP+TLS early for a host you will need |
| Compression (gzip, Brotli) | transfer time |
| Caching headers | the whole request, for a repeat visit |
8. From HTML to pixels
The response is only the start. The browser:
- Parses the HTML into the DOM (a tree of elements). While parsing it finds more resources: stylesheets, scripts, images, fonts, and requests them (reusing the connection where it can, in parallel over HTTP/2).
- Parses the CSS into the CSSOM. CSS blocks rendering: the browser will not paint until it knows the styles, to avoid flashing unstyled content.
- Runs JavaScript. A normal
<script>blocks the parser until it has downloaded and run, because it may change the document.defer(run after parsing, in order) andasync(run when ready) avoid that. Script can also change the DOM and CSSOM. - Builds the render tree (visible elements with their computed styles), then does layout (sizes and positions), paint (draws the pixels into layers), and composite (puts the layers on screen, using the GPU).
- Keeps going: images and fonts arrive, scripts run, user input triggers events and updates. Changing a size forces layout again; changing only a color forces a repaint; animating
transformoropacitycan often stay on the compositor, which is why it is smooth.
The timing words you will hear: TTFB (time to first byte), First Contentful Paint, Largest Contentful Paint, and Interaction to Next Paint. They are the user-visible result of everything above.
9. Common follow-up questions
"What details did you leave out?"
Three that real browsers use: Happy Eyeballs (RFC 8305), which tries IPv6 and IPv4 almost at once and keeps the first connection that works; HTTPS and SVCB DNS records (RFC 9460), which can tell the browser in the DNS answer that the site supports HTTP/3 and which address to use, saving a step; and service workers, scripts a site installs that can answer requests from a local cache before the network is touched.
"What if the DNS answer is wrong or the name does not exist?"
The resolver returns NXDOMAIN (no such name) or SERVFAIL, and the browser shows an error. A wrong cached answer lives on until its TTL expires, which is why you lower the TTL before a planned migration.
"What changes with HTTP/3?"
It uses QUIC over UDP. The transport and the TLS 1.3 handshake happen together (one round trip, or none for a resumed connection), streams are independent, so one lost packet does not stall the others, and a connection can survive a change of network (Wi-Fi to mobile).
"What does a proxy or CDN change?"
DNS answers point to the CDN, so TCP and TLS end at a server close to you. If it has the content cached it answers directly; otherwise it fetches from your origin and keeps a copy (see caching strategies).
"Where could it fail?"
Name not found; no route or a firewall; port closed (connection refused) or no answer (timeout); certificate invalid; server overloaded (5xx); a blocking script that never finishes. Each failure shows up at a different step, which is how you tell where to look. The tools: dig (DNS), ping and traceroute (reachability), curl -v (TCP, TLS, HTTP), the browser's network panel (the waterfall of all requests), and openssl s_client (TLS).
"What happens on the server?"
The request goes through the load balancer to a web server or application server, which routes it to a handler, checks authentication, reads or writes data (often via a cache first), and renders a response. This is where most of the other guides on this site pick up.
10. Things to mention in an interview
- Keep the order: URL parse and caches, DNS, TCP, TLS, HTTP, server, then browser rendering.
- Give a number or a detail for each step: TTL and caching for DNS, one round trip for TCP, one for TLS 1.3, a request that may be redirected, and render blocking CSS and scripts.
- Say where the time goes (round trips) and the standard fixes (reuse connections, caches, CDN, HTTP/3).
- Mention that a repeat visit may skip nearly everything thanks to caches.
- Be ready to go one level deeper on whichever step the interviewer picks.
Quick recap
- The browser parses the URL and checks its caches and HSTS list.
- DNS turns the name into an address; answers are cached for the TTL.
- TCP opens a connection (one round trip); TLS secures it (one more in 1.3).
- The HTTP request and response follow; redirects restart the sequence.
- The browser builds the DOM and CSSOM, runs scripts, lays out, paints and composites.
- Latency is mostly round trips; reuse connections, cache, and move content close to the user.
Sources
- IETF, RFC 1035: Domain Names, Implementation and Specification. The DNS message format used for the 29-byte query.
- IETF, RFC 9293: Transmission Control Protocol. The handshake and reliable delivery.
- IETF, RFC 8446: TLS 1.3.
- IETF, RFC 9110: HTTP Semantics and RFC 9114: HTTP/3.
- IETF, RFC 9000: QUIC.
- IETF, RFC 6797: HTTP Strict Transport Security, RFC 8305: Happy Eyeballs Version 2 and RFC 9460: SVCB and HTTPS resource records.
- curl documentation, the
--write-outvariables (time_namelookup,time_connect,time_appconnect,time_starttransfer). - web.dev, Core Web Vitals. The user-facing loading metrics.
Practise this topic: Networking