The last section watched HTTP traffic from the server's side: access logs, metrics, and traces, all written after a request has already happened. This section flips the camera around to the developer's own machine, where you can watch a request the moment it leaves and the moment it comes back. The first tool you reach for is built into the browser you already have open: the Network panel in DevTools.
It is the fastest way to answer "what did this page actually request, and what came back?" Better still, almost every concept from the earlier sections becomes visible here. The DNS lookup, the TCP connection, the TLS handshake, the cache hit, the redirect chain, the HTTP version — they all show up as rows and bars you can click on.
Every major browser ships the same tool under slightly different names. In Chrome, Edge, and Firefox you open DevTools with F12 (or Cmd+Option+I on a Mac, Ctrl+Shift+I elsewhere), then click the Network tab. Safari calls it the Web Inspector and you enable it once under Settings → Advanced → "Show features for web developers."
One habit to build immediately: the Network panel only records requests that happen while it is open. If you open it after the page has loaded, the table is empty. So the normal move is open DevTools first, then reload the page, and watch the rows fill in. There is usually a "Preserve log" checkbox too — leave it on when you are debugging something that navigates or redirects, otherwise the table is wiped clean on each new page and you lose the evidence you were chasing.
When the page loads, you see one row per request. A modern page is not one request, it is dozens: the HTML document, then every stylesheet, script, font, image, and API call that document pulls in. Each row is a request, and the columns are a quick summary of what happened.

You can show or hide columns by right-clicking the header, but six of them carry most of the signal:
style.css, /api/orders/42, hero.jpg). This is how you find the specific request you care about in a long list.200s is healthy, and a red 404 or 500 jumps out. You will also see 301/302 here for redirects and 304 Not Modified for a successful cache revalidation.document, stylesheet, script, font, xhr/fetch for API calls, png/jpeg for images). Handy for filtering: when you only care about your API calls, you filter to the Fetch/XHR type and the noise disappears.h2 for HTTP/2, h3 for HTTP/3 over QUIC, http/1.1 for the older one. This column is the easiest way to confirm which version a site negotiated, the thing we discussed back in the connections chapter.A small thing worth knowing early: the filter box at the top of the panel takes plain text (type orders to see only requests with "orders" in the name) and a handful of special filters like status-code:500 or method:POST. When a page makes a hundred requests, the filter is how you get down to the one that matters.
The table is the overview. Click any row and a detail view opens beside it, split into tabs. The names vary slightly between browsers, but the four that matter are consistent:
Authorization header went out, what Content-Type came back, or which Cache-Control the server set.POST or PUT. If you sent JSON, you see the JSON; if you submitted a form, you see the form fields.The Time column tells you a request was slow. The Timing tab tells you why. It splits the request's lifetime into phases, drawn as a stacked bar, and each phase maps onto a layer you already learned earlier in the course.

Reading the bar left to right:
http:// page this phase is simply absent.Here is the insight that makes the bar worth reading: everything before Waiting is connection setup. DNS, the TCP handshake, and the TLS handshake all happen before your request body is even sent. That is exactly why connection reuse and keep-alive matter so much, and why the first request to a new host is slower than the rest. On later requests over the same connection, those first phases collapse to nothing and the bar is almost all Waiting and Download.
A common confusion: a slow Time with most of it in Waiting is a backend problem (the server is slow to respond), while a slow Time with most of it in Content Download is a payload or bandwidth problem (the response is too big). They look identical in the Time column and completely different in the Timing tab. That distinction alone changes who you go talk to.
The numbers are usually small and add up, so do not over-interpret a few milliseconds. The point of the breakdown is the shape: which phase dominates tells you which layer to suspect.
The caching section spent a lot of time on what should be cached. The Network panel shows you what actually was. Look at the Size column. When a response is served from the cache, the byte count is replaced with a label instead of a number:
(memory cache) — served from the browser's in-memory cache. Instant, and gone when you close the tab. You will see this for assets reused within the same page session.(disk cache) — served from the browser's on-disk cache. Survives a restart, and still much faster than a network round trip.A 304 Not Modified status is a different, related win. There the browser did talk to the server (a small conditional request using the ETag or Last-Modified we covered in the cache-validation chapter), but the server confirmed the cached copy is still good, so no body came back. A 304 costs a round trip; a (memory cache) or (disk cache) hit costs nothing. Both beat re-downloading the file.
This is also where the reload type matters. A normal reload uses the cache where it is allowed to. A hard reload (Cmd+Shift+R / Ctrl+Shift+R) tells the browser to ignore the cache and fetch everything fresh, which is exactly what you want when you are testing whether a fix actually shipped versus seeing a stale cached file.
Two more things the panel makes obvious without any extra tooling.
Redirects show up as their own rows. If you request http://github.com you will see a 301 row whose response points elsewhere, then the row for the page it landed on. With "Preserve log" on, the whole chain stays visible, so a redirect loop (the same 301 repeating, or a chain that never reaches a 200) is immediately obvious as a stack of redirect rows. That is the same chain you would follow with curl -L, just drawn out as a list.
The HTTP version is right there in the Protocol column we mentioned earlier. If it is not shown, right-click the column header and enable "Protocol." Seeing h2 or h3 confirms the site negotiated HTTP/2 or HTTP/3; http/1.1 tells you it fell back to the older version. No special command needed, you just read the column.
Sometimes you find the broken request in the panel and want to poke at it repeatedly: change a header, drop a cookie, run it again, run it ten times. Doing that by clicking through a browser is slow. The browser has a bridge for exactly this.

Right-click any request in the table, choose Copy → Copy as cURL, and the browser hands you a complete curl command for that exact request: the same URL, the same method, every header the browser sent, the cookies, and the request body. Paste it into your terminal and you have reproduced the browser's request precisely, outside the browser.
This matters for two reasons. First, it removes the browser from the equation. If the curl command fails the same way, the bug is on the server, not in your front-end code. Second, it gives you a starting point you can edit freely without the browser fighting you. That bridge is exactly where the next chapter picks up: driving HTTP from the terminal with curl, where you control every byte of the request.
Open any site you use often. Open DevTools, click Network, and reload the page so the table fills with rows.
(memory cache) or (disk cache) — the second visit reusing what the first one fetched.In one minute you have found a page's slowest request and explained why it was slow, using nothing but the browser. That is the panel earning its place as your first debugging tool.
The Copy as cURL command you just learned is the handoff. Next we move into the terminal and drive HTTP with curl directly, so you can reproduce and isolate any request byte by byte.