How to Read a Network Waterfall: Mapping Slow Pages from Start to Finish
The first request in any waterfall chart is the HTML document – the initial page load that sets the pace for everything else. Open up the Network panel in Chrome's DevTools, and you'll see it at the top, labeled as a document type with a long colored bar spanning its duration. This bar is your anchor point: it shows the duration, from the URL of that first HTML bootstrap, to the final byte delivered for its integrity.
To diagnose a slow page, everything depends on how that first bar shapes up – and that depends on what each color segment inside it really means.
Start at the Top – The HTML Request That Sets the Pace
Identifying the first document row in the waterfall chart is essential. This initial request is the root cause of the timeline for all subsequent subresources. As the HTML document loads, the browser parses it and generates independent requests for the referenced assets – CSS, JavaScript, images, and other multimedia files. Each of these subresources will start loading once the HTML document has been partially parsed and the references to them are encountered.
Look at the bar corresponding to the HTML document in the waterfall. The length of the bar represents the total amount of time from when the browser starts requesting the resource until the last byte is received. Notice how other subresource requests align with this bar – they don't start until after the document request has begun. In a slow page, this initial bar is often longer, indicating a slow server that can't keep up.
The Waterfall column isn't just a visual marker; it's a timing breakdown. Hover over the HTML document bar or open its Timing tab to see how it segments into different phases of activity, such as DNS resolution, TCP handshake, SSL negotiation, waiting for the first byte, and finally, receiving the content.
If the "waiting" state (represented by a green segment) dominates, the server is slow. If the "content download" state (represented by a blue segment) dominates, the payload is too large or the bandwidth is insufficient. Crafting a diagnosis starts from this first bar – and understanding that its total duration in the Time column is not "server time" but total time from request to completion, whether it hung due to payload, network, or server.
Reading the Columns
Stretching across the network panel beneath the waterfall chart are six default columns: Status, Type, Initiator, Size, Time, and the Waterfall chart itself. Each has its part to play in constructing a diagnostic hypothesis.
- The type labels what kind of resource is being loaded (HTML document, image, script, stylesheet, etc.). Think of it like a traffic cop directing the browser's attention to different roads: a crucial step in organizing the flow of bytes.
- The initiator tells you what in the source code triggered the network request, linking a symptomatic bar back to the exact command the developers used. Every network request must flow from an initiator. The network panel is a window into the developer's intent.
- The size column is crucial for diagnosing long download segments (represented in blue). It shows both the compressed size transferred over the wire and the actual size of the resource. Large blue bars with a high ratio of actual to transferred size suggest that even with compression, the payload to be sent and received is large.
- The time column gives the total duration from the start of the request until the browser has finished receiving the last byte. Too often, this duration is incorrectly misattributed as server time. The latency (first byte time) is also shown, revealing just how much of the "waiting" time happens at the server side versus in transferring the payload. Distinguishing between waiting (green) and downloading (blue) phases is crucial.
The waterfall chart paints a visual picture showing the actual flow of bytes over time. Think of it as dough rising with the ingredients arriving to make the simplest bread, before working through each part of the daily baking. And being a visual artifact, unique distinguishing shapes in the waterfall are crucial diagnostic clues. We will get to brainstorming those recognizable patterns in the next section.
Timing Anatomy
Each waterfall bar is broken down by timing phases. The color segments tell the story of what happened from dispatch to delivery, once you know what each color represents.
- Queueing and stalled states: When you hover over an entry, you might see a "queueing" or "stalled" segment. This state represents a known resource waiting to be dispatched to the network process. It's outside of the first byte and content download waiting you see in plain sight. Documentation5 shows that Chrome separates queueing (known but not yet dispatched) from stalling (dispatched but waiting for a connection slot). Early dispatching queues can often surface when too many simultaneous requests are made at once. These segments aggregate multiple TCP/TLS/HTTP states - in other words, queueing can overlap with SSL negotiation, too.
- DNS lookup: If a new domain is involved, there may be an additional segment representing the browser looking up its network location. This is rarely problematic in a well-configured setup, but in an ill-configured one, the DNS cache might be reset for every resource.8
- TCP handshake: The handshake establishes a connection to send the request to and receive the response
- TLS negotiation: For resources served over HTTPS, this establishes the security handshake between client and server. It's often delicate if using outdated software.
- Waiting (TTFB – Time to First Byte): This segment represents the time until the first byte comes to the browser from the server. It's a combination of network round-trip time, server processing, and any send-buffer queuing latency. This is normally dominated by the server.11
- Content Download: This segment represents the time taken to transfer the payload. It is often dominated by payload size and bandwidth.1
Hoving over a segment will break it down into these different bars and explain their duration. Open a waterfall bar's Timing tab to diagnose timing in its context, so that the part dominating the time becomes clear.
If you see long "waiting" bars, check if network round-trip time was high, if any server resource contention happened, or if potentially too many HTTP versions/chunks sent by the browser keep it backed up.
If the content download segment is long, relate this to the Size column – large payloads can be the culprit, especially in a slow network, or when the transfer is poorly compressed.
If the bar starts with a long queueing segment and you have a long line of stacked bars, you may have run out of bandwidth or connection slots. Disabling cache and enabling the Priority, Connection ID, and Protocol columns in the network panel can help you investigate those roots.
Reading the Shapes
Keen eye for recurring patterns in the shapes of waterfall bars can lead straight to specific problems. Learning to spot them can save you a lot of reading and tracking down blocks of code.
One common type of shape is the stacking of several non-HTML rows, all lined up vertically, like a bunch of kids all starting a race at the same time. This probably means that the browser opened up multiple simultaneous connections to the server, and they all started loading at the same time, so the bars are all lined up.
Another shape to watch is the "waterfall staircase" effect: a long gap after a hierarchical series (typically where a parent resource is loaded, and then its children in turn). Each resource has to have the one before it, so you often see these in an heirarchical order: one after the other in series.
Yet another common shape is a series of requests, each starting before the previous one finishes. This can be a symptom of a long series that can be parallelized, although of course if they're dependency-ordered then that's necessary. If they're run in series but there's no dependency, it's a candidate for parallelization.
A late-critical-blocking operation (often CSS but sometimes JavaScript) shows up as one long bar with many dependencies hanging off it, because the blocker runs first and the dependencies then follow it. This is a common sign of a non-optimized experience flow.
When using HTTP/2, the dependency line in each row shows which request triggered which. This lets you diagnose sites doing "Make Payment" dependency series within XMLHttpRequest (XHR) calls which then uses javascript calls to carry out tasks, and then waits for them all synchronously.
Mnemonics for each color can help you recall which phase is which. A purple send phase typically means there was lots of HTTP chunked transfer encoding, which can be from the browser splitting the request or server splitting the response. The grey waiting phase before the byte actually starts downloading often coincides with the browser actually processing the bytes it's downloaded, converting depending on the resource type. The extra-long green parts should jog you to try to find a way to lazy load.
From Shape to Cause
Spotting the general timing shapes is just a start - the next step is relating it to practical site issues:
- If you see multiple stacked bars consuming lots of browser slot time, you may need to reduce the number of parallel connections, or ideally parse HTML until you can then start some other downloads; it will often help at least to queue CSS in the order of importance.
Large waiting times (green segments) on the initial HTML document bar indicate a slow server. Check the server's CPU, memory, or network bandwidth. If green segments dominate consistently, server-side optimizations (like persistent connections, HTTP keep-alive, server-side caching, or response compression) are needed. If long blue (content download) segments dominate, increase bandwidth, reduce payloads, or optimize deliveries. Use image optimizers, CSS minimizers, font subsets, and resource serving strategies like prefetch, preload, lazy load, deferred, etc. Check the time span your browser dedicates to JavaScript parsers, and move non-critical parsing and other processing out of the paint cycle and off of the main thread. If multiple large parallel resource requests are all aligning, you may have opened multiple connections that act in a resourced-constrained way? Think whether resources could be lazy-loaded or defer-loaded? Is HTTP/2 viable for smarter multiplexing? Or you could design to shard load dispatching to offload to multiple subdomains to get extra connection room. Be conscious of what you make parallel. * Look at off-network work - any OS, JVM, or other process that takes up main thread CPU and stalls on a resource. Use the Chrome DevTools main performance thread to sanity check here.
Practicing the Skill
Resourced constrained waterfalls are still art, depending on lots of site specifics. But with practice, the shapes start speaking. Your goal is to quickly grasp the whole situation from the overall shape.
Quick steps to diagnose from Chrome DevTools:
- Open the DevTools' Network tab
- Enable the "Show timing breakdown" checkbox under the filters
- Reload the page
- Sort the network entries by the "Waterfall" column
- Look for long bars – they're your suspects
When in doubt, hover over a suspicious bar in the waterfall. Chrome DevTools will break down its time and hygiene. Clicking on a row will bring up a right sidebar with timing details on DNS, TCP, SSL, queueing, first byte, and transfer times, then listed resources in that request.
Long-color-dominated bars are your first clue: blue means your bandwidth is your problem, and green means it's your server. If they all line up vertically, you may be using too many connections. Check the Size column to confirm if the payload is too large. Flush cache, if there is one, or use different ones, before the site test. Enable the Count and mainly the Priority and Protocol columns for insights. Chrome DevTools exposes queueing phases as grey segments within the bar of a resource. Based on guidance, healthy queueing is under 10 ms, 10–50 ms merits investigation, and over 50 ms often indicates you've exhausted concurrent connections or there is a priority inversion.
With practice, you can quickly navigate the waterfall without cache to see fresh timing metrics, allowing you to track down if a specific opaque script or panel structure is offending, and trimming it.
The waterfall is not a diagnostic fantasy - it's a repeatable practice based on reading a browser's known phases, column hypotheses, and distinguishing shapes. Critically think about every bar - not just as a source code path, but as a resource that takes runtime to flow. Familiarizing yourself with DevTools and common patterns is how you turn a static chart into a diagnostic skill.