URL bar to first byte
Your entry point to how the web works under the hood, the four network stages a request crosses before a page can load, on the 2026 HTTP/3 stack.
A slow page load is rarely one problem. A request crosses four stages between the moment you commit a URL and the moment the first byte comes back, and usually one of those stages is the bottleneck while the other three are fine. An engineer who can look at a single waterfall row and name the slow stage starts debugging in the right place. One who reads “the site is slow” and jumps straight to the server logs can lose half a day checking something that was never the problem.
This lesson maps that route. The four stages are DNS, transport, TLS, and HTTP, named in the 2026 vocabulary, and each one gets a prose section and a labelled spot on a shared diagram. A fifth section covers reading the DevTools Network panel, where you’ll spend most of your debugging time through the rest of this unit. What happens after the first byte arrives, the browser side of the pipeline, is the next lesson. A deeper TLS treatment at debugging depth comes later in this chapter.
Before going further, open DevTools (Cmd+Opt+I on macOS, F12 on Windows or Linux), switch to the Network tab, right-click any column header, and turn on the Protocol column. Leave it open. You’ll use it mid-lesson.
The four-stage map
Section titled “The four-stage map”Here’s the whole route a request takes, end to end. Look at it once before reading the prose, since each stage below refers back to this diagram.
%%{init: {'themeCSS': '.messageText, .messageText tspan, .actor, .actor tspan, .noteText, .noteText tspan, .labelText, .labelText tspan { font-size: 18px !important; } .loopText, .loopText tspan { font-size: 16px !important; }'} }%%
sequenceDiagram
participant B as Browser
participant R as Resolver
participant S as Server
rect rgba(56, 189, 248, 0.12)
Note over B,S: Stage 1 — DNS · ~20-80 ms cold, ~0 ms warm
B->>R: query example.com (A + AAAA)
R-->>B: 2606:4700:: / 104.16....
Note over B,R: Happy Eyeballs v2 races IPv6 and IPv4
end
rect rgba(34, 197, 94, 0.12)
Note over B,S: Stages 2+3 — Transport + TLS folded into QUIC · 1 RTT fresh, 0 RTT resumed
B->>S: Initial (ClientHello + QUIC frames)
S-->>B: ServerHello + cert + handshake
B->>S: Finished
Note over B,S: HTTP/3 over QUIC on UDP/443 — TLS 1.3 folded in
end
rect rgba(244, 114, 182, 0.12)
Note over B,S: Stage 4 — HTTP request · TTFB
B->>S: GET / HTTP/3
S-->>B: 200 + first byte
end Read the diagram top to bottom. The horizontal arrows are network round trips. Each one is a real journey between the client and a remote machine, and each one costs wall-clock time. Stages 2 and 3 are drawn together because in 2026 they are physically the same handshake: TLS 1.3 is folded into the QUIC transport setup, so the secure pipe gets built in one round of negotiation rather than two. Stage 4 is the actual HTTP request, the one that carries a method and a path. Stages 1 through 3 are the cost of getting ready to make that request. An experienced engineer debugging a slow page checks those setup stages first, because on a warm connection they collapse to near zero, as the numbers in the next four sections show.
Stage 1: DNS resolution
Section titled “Stage 1: DNS resolution”The browser is given a hostname like app.example.com, but the network stack can’t open a connection to a hostname. It needs an IP address, and turning one into the other is what DNS does.
The browser hands the hostname to the OS resolver, and the resolver walks a chain of caches looking for the answer. It checks the browser’s own cache first, then the OS cache, then the recursive resolver your network is configured to use (often your ISP’s, increasingly Cloudflare’s or Google’s), and finally the authoritative server for the domain if nothing along the way had the answer. A cold lookup, with nothing cached anywhere, typically costs 20 to 80 milliseconds. A warm lookup costs effectively zero.
In 2026, that resolver conversation is increasingly encrypted. The standard form is DoH , where the DNS query rides inside an HTTPS connection to a DNS provider that speaks the protocol. Firefox enables DoH by default in most regions, and Chrome and Edge auto-upgrade to it when the system resolver advertises support, falling back to plain DNS otherwise. Plain DNS is the floor the stack drops to when nothing better is available, not the default. Two other encrypted forms exist: DoT (DNS over TLS) is the OS-level alternate, and DoQ (DNS over QUIC) is the QUIC-native one. They’re worth naming so you don’t assume DoH is the only encrypted option, but DoH is the production reality the course assumes.
The browser does something here that most newcomers don’t picture: it doesn’t issue one lookup, it issues two and races them, an A record query for IPv4 and an AAAA query for IPv6. The algorithm is Happy Eyeballs v2 . When both families resolve in time it prefers IPv6, giving it a roughly 50 ms head start, but it never waits on IPv6: if v6 is broken, v4 wins and the user notices nothing. Without this race, a misconfigured IPv6 path would stall the page for the resolver’s full timeout.
Stage 2: Transport, HTTP/3 over QUIC
Section titled “Stage 2: Transport, HTTP/3 over QUIC”Once the browser has an IP address, it needs to open a connection to it. The 2026 default is QUIC on UDP port 443, carrying HTTP/3.
HTTP/2 over TCP solved a real problem, multiplexing several requests on one connection, but it solved it at the HTTP layer. The transport underneath was still TCP, and TCP delivers bytes strictly in order: if one packet drops, every later packet on the connection waits for it, even packets that belong to a different stream. That stall is head-of-line blocking, and on a flaky mobile network it wrecks throughput. QUIC moves multiplexing down into the transport itself, so each stream keeps its own state and a lost packet holds up only the stream it belonged to. It also folds in TLS 1.3 (Stage 3 below) and pushes encryption deeper into the stack, so even the transport metadata is encrypted.
The browser doesn’t gamble on HTTP/3 for a brand-new origin. It opens its first connection over HTTP/2, sees the Alt-Svc response header advertising that HTTP/3 is available, and upgrades on the next request. A newer mechanism, the HTTPS DNS record (type 65 / SVCB), lets a browser learn about HTTP/3 from the DNS lookup itself. That mechanism is growing, but Alt-Svc is still the most common discovery path in 2026. You’ll see the practical consequence in the DevTools drill at the end of this lesson: the very first document request to a fresh origin can show h2, and the second navigation flips to h3. That isn’t a bug, just the browser learning the origin supports HTTP/3.
The fallback path still matters, because HTTP/2 over TCP plus TLS 1.3 is everywhere. Corporate networks sometimes block or throttle UDP, and clients then fall back to HTTP/2 silently. Origins that haven’t moved still serve HTTP/1.1 to clients that handshake it. The course writes no HTTP/1.1-specific code.
The round-trip story is what makes QUIC worth the change. It’s clearest with three cases set side by side.
Client -> Server : Initial + ClientHello + (early HTTP request frames)Server -> Client : ServerHello + cert + handshake + FinishedClient -> Server : Finished + HTTP request body (continues...)One round trip sets up the connection, and the request goes out the moment the handshake completes. No session ticket exists yet, but TLS 1.3 inside QUIC needs only one round trip to establish keys, and the request follows immediately. Latency to the first byte works out to roughly two round trips: one for the handshake, one for the response.
Client -> Server : Initial + early data (HTTP request inside the first packet) using a cached session ticket from a previous visitServer -> Client : response (first byte)A repeat visit to the same origin. The browser still holds a session ticket from the previous handshake, and it uses that ticket to send the HTTP request inside the very first packet, the 0-RTT path. Latency collapses to roughly one round trip, the response itself. Early data is only safe for idempotent GETs; non-idempotent requests wait for the full handshake even on resumption.
Client -> Server : SYN (TCP handshake)Server -> Client : SYN-ACKClient -> Server : ACKClient -> Server : ClientHello (TLS 1.3 handshake)Server -> Client : ServerHello + cert + FinishedClient -> Server : Finished + HTTP requestServer -> Client : response (first byte)TCP handshake first, then TLS, then the request. That’s two round trips to the first byte on a fresh connection. This is how the web worked before QUIC, and it’s still where a request lands when UDP is blocked or before Alt-Svc has done its work.
The number to remember: fresh QUIC is 1 RTT, resumed QUIC is 0 RTT, TCP plus TLS is 2 RTT. On a mobile connection where one round trip can be 100 ms or more, that’s the difference between a snappy page and a sluggish one.
Stage 3: TLS 1.3 inside the QUIC handshake
Section titled “Stage 3: TLS 1.3 inside the QUIC handshake”This section stays short on purpose. The deeper TLS treatment, covering cipher suites, certificate chains, SNI, and ALPN, lives in the HTTPS on localhost lesson later in this chapter, framed against mkcert and local HTTPS. Here, four facts are enough to make sense of the diagram and the RTT counts.
TLS 1.3 is the only flavor the 2026 stack ships. TLS 1.2 is deprecated, and the browser refuses to speak older protocols. Treat it as a given.
In QUIC, TLS is interleaved with the transport handshake. The ClientHello rides inside the very first QUIC packet rather than as a separate step on top. A fresh connection completes in one round trip; a resumed connection completes in zero, using a session ticket the client kept from the previous visit.
0-RTT carries a replay-safety constraint. Early data is the request bytes carried inside the first packet on a resumed connection. Those bytes have no fresh nonce from the server yet, so an attacker who recorded the encrypted packet could replay it later, and the server would have no way to tell the replay apart from the original. The fix is to send only idempotent GETs as early data; non-idempotent requests, meaning POST, PATCH, DELETE, or anything else that changes state on the server, wait for the full handshake. The browser and the HTTP/3 stack handle this for you. The rule is still worth knowing, because the next chapter on the HTTP contract leans heavily on idempotency as the property that makes safe retries possible.
TLS 1.3 always gives normal traffic forward secrecy. Even if the server’s long-term private key leaks tomorrow, recorded sessions from yesterday stay undecryptable, because each session uses its own ephemeral keys. The one exception is 0-RTT early data, which has no forward secrecy: by construction the request rides on keys derived before the new ephemeral exchange. That’s one more reason early data is reserved for idempotent GETs.
The full TLS 1.3 handshake, including cipher-suite negotiation, the ALPN identifiers (h3, h2, http/1.1), SNI (Server Name Indication), and certificate chain validation, is the subject of the HTTPS on localhost lesson later in this chapter. All this section needed was the round-trip count and the resumption story.
Stage 4: The HTTP request and TTFB
Section titled “Stage 4: The HTTP request and TTFB”Once the secure transport is up, the client finally sends what it came for: an HTTP/3 request. It carries a method (GET), a path (/), a :authority pseudo-header naming the host, the request headers, and, for non-GET requests, a body. The server processes it and starts responding, and the first byte of the response body arrives.
The wall-clock time from the moment the browser commits the URL to the moment that first byte lands is TTFB . It’s a single number on the stopwatch, but it is not a single thing. It bundles every stage above: DNS, connection setup, TLS handshake, request travel, server thinking time, and the network round trip for the response.
TTFB is the metric the performance chapter in Unit 19 tunes against. Here it’s just a label, and the point is that a slow server is only one possible explanation, with three others sitting upstream of it.
Reading the DevTools Network waterfall
Section titled “Reading the DevTools Network waterfall”You opened DevTools at the top of the lesson. The Network panel is where every later chapter in this unit will send you. Each row in the panel is one request, and each row carries a Protocol label and a Timing breakdown that map directly onto the stages above.
The Protocol column
Section titled “The Protocol column”The Protocol column you enabled at the top tells you which version the request used. The three values you’ll see:
h3: HTTP/3 over QUIC. The 2026 default.h2: HTTP/2 over TCP + TLS. The fallback, and also the first hit to a fresh origin beforeAlt-Svcdiscovery has happened.http/1.1: Legacy. Origins that haven’t moved, or clients on networks that block UDP and fall back past both the HTTP/2 and HTTP/3 hints.
The Alt-Svc nuance from Stage 2 shows up here. On a fresh origin, the very first document request can show h2; reload the page and the document row should flip to h3, because the browser has now learned HTTP/3 is available. If a production origin still isn’t h3 on a second load, that’s a configuration conversation with whoever manages the origin’s CDN, not a bug in your code.
The Timing breakdown
Section titled “The Timing breakdown”Click a row in the Network panel, switch to the Timing tab, and you’ll see a stacked bar. Each segment is one of the stages this lesson named, and they map straight across:
- Queued / Stalled : the browser’s own bookkeeping. The request is waiting on a connection slot or a priority queue.
- DNS Lookup : Stage 1. Often shows 0 ms on warm caches.
- Initial connection : Stage 2. For
h3requests, the QUIC handshake collapses into this segment. Forh2, this is just the TCP handshake. - SSL : Stage 3. For
h3, it’s folded into Initial connection and often not shown as a separate bar. Forh2, it’s the explicit TLS round trip on top of TCP. - Request sent: bytes uploaded. Usually tiny for a
GET. - Waiting (TTFB) : Stage 4. Server thinking time plus the round trip back.
- Content Download : body bytes streaming in.
That’s the whole vocabulary of the panel. Once you’ve read a few real waterfalls with these labels in mind, every later debugging conversation in this unit lands somewhere on this list.
The drill: read a real request
Section titled “The drill: read a real request”Now do it on a real site. Follow the steps below against cloudflare.com (always served over h3 on a modern browser) or against this course’s site.
-
In DevTools, switch to the Network tab. In the toolbar at the top of the panel, tick Disable cache. This forces a real network fetch instead of a cached response.
-
Hard-reload the page (Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows or Linux). Watch the document row, the very first row, the one for the page’s HTML.
-
Check the Protocol column. On the first load to a fresh origin you may see
h2; do one more reload and the document row should flip toh3, because the browser learned about HTTP/3 from theAlt-Svcheader on the first response. Click the document row, open the Timing tab, and find the DNS Lookup, Initial connection, Waiting (TTFB), and Content Download segments. Onh3, the SSL bar collapses into Initial connection, which is the transport-plus-TLS fold the diagram showed. -
Untick Disable cache and do a soft reload (Cmd+R or F5). The DNS Lookup and Initial connection segments should collapse to near zero. That’s the resumed-connection effect made visible: the DNS is cached and the QUIC connection is still alive.
-
Click the Waiting (TTFB) segment and read its number. That’s the server-and-network cost in isolation, with all the setup costs already paid in previous requests.
For reference, here’s what an annotated h3 timing breakdown looks like, with each label mapped to its stage from the diagram.
The waterfall is where you’ll read the network for the rest of Unit 2. Every fetch you make later in the unit, every cookie you set, and every CORS preflight shows up here as a row you can hover, click, and read. The vocabulary you just learned stays with you: h3 versus h2, the DNS / Initial connection / SSL / Waiting / Content Download segments, and fresh versus resumed connections.
Read the waterfall by its dominant cost
Section titled “Read the waterfall by its dominant cost”One short drill before closing. The whole point of the four-stage map is to look at any waterfall row and name which stage is the bottleneck, because that’s the move that lets an experienced engineer aim their debugging. Match each row’s shorthand description to the stage that dominates its time.
Match each waterfall row shorthand to the stage that dominates its wall-clock time. Click an item on the left, then its match on the right. Press Check when done.
h3 · DNS 0 ms · Initial connection 0 ms · Waiting (TTFB) 320 ms · Content Download 12 msh2 · DNS 75 ms · Initial connection 90 ms · SSL 80 ms · Waiting (TTFB) 60 ms · Content Download 8 msh3 · Queued 0 ms · DNS 60 ms · Initial connection 35 ms · Waiting (TTFB) 50 msh3 · Queued 280 ms · DNS 0 ms · Initial connection 0 ms · Waiting 40 msh3 · Waiting (TTFB) 30 ms · Content Download 1800 ms(from disk cache) · 0 ms totalIf you can read these six rows and name the slow stage, you can do it for any row in production. Naming the stage before you start debugging is the skill worth keeping from this lesson. Protocols will turn over and the vocabulary will drift, but the staged mental model survives both.
What stays out
Section titled “What stays out”A few topics belong nearby rather than here. Each is named once so you know where it lands.
The HTTP method, status, and header contract (GET / POST / PUT / PATCH / DELETE, the status-code families, the header categories) is the next chapter’s full territory. Origins and CORS are the chapter after that, and cookies with Secure and SameSite are the one after that. The deeper TLS 1.3 handshake at debugging depth, covering cipher suites, the full certificate chain, SNI, and ALPN, is the HTTPS on localhost lesson later in this chapter, where you’ll wire up https://localhost with mkcert. The browser-side pipeline, what happens after the first byte arrives along the parse-DOM-CSSOM-layout-paint-composite path, is the next lesson.
The first byte is here. In the next lesson, it becomes pixels.
External resources
Section titled “External resources”Cloudflare's Learning Center overview — QUIC, head-of-line blocking, 0-RTT, and why HTTP/3 sits on UDP.
Free interactive book by Daniel Stenberg (curl maintainer) — the deepest readable treatment of HTTP/3 and QUIC outside the RFCs.
Official Chrome DevTools docs — every column, filter, and Timing-tab segment of the Network panel.
Background on RFC 8305 — how browsers race IPv6 and IPv4 to avoid the broken-family stall.