Waterfall Timeline
The Waterfall Timeline shows the timing of every request in your session as horizontal bars on a shared time axis — like a Gantt chart for network traffic. Each bar represents one HTTP request, and its position and width show when the request started and how long it took. Color-coded segments within each bar break down where time was spent: DNS resolution, TCP connection, TLS handshake, waiting for the server to respond (TTFB), and transferring the response data.
This view answers questions that the regular flow list can’t: “Which requests happened in parallel?”, “Where’s the bottleneck — is it DNS, TLS, or the server?”, “How do the requests triggered by this button click relate to each other in time?”
Ghost has two waterfall views: the multi-flow timeline (replaces the traffic list) and the single-flow timing detail (an overlay in the flow inspector). Both are described below.
Multi-Flow Waterfall
Section titled “Multi-Flow Waterfall”Switch to the waterfall view using the view mode toggle in the toolbar (list icon / waterfall icon). The toggle is stored in Ghost’s UI state — switching back to list mode preserves your position.
┌──────────────────────────────────────────────────────────────────┐│ 0ms 200ms 400ms 600ms 800ms 1000ms │├────────────────┬─────────────────────────────────────────────────┤│ ◆ Click #cart │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░ POST /api/cart 142ms││ │ ▓▓▓▓▓▓▓░░░░░ GET /api/stock 89ms ││ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ GET /images/cart.png │├────────────────┼─────────────────────────────────────────────────┤│ Background │ ▓▓░░ GET /api/heartbeat 12ms ││ │ ▓▓░░ GET /api/config 8ms │└────────────────┴─────────────────────────────────────────────────┘ ■ DNS ■ TCP ■ TLS ■ TTFB ■ TransferLayout
Section titled “Layout”The waterfall has three main areas:
| Area | Width/Height | Purpose |
|---|---|---|
| Label column | 260px (fixed) | Shows the HTTP method badge, status code, and path (truncated to 35 characters) for each flow |
| Time axis | 28px tall, sticky at top | Shows 6 evenly-spaced tick marks with timestamps (milliseconds or seconds). Stays visible as you scroll. Has a frosted glass background (bg-ghost-900/95 backdrop-blur-sm). |
| Bar area | Remaining width | The actual timing bars, with vertical grid lines at each tick position |
Each flow row is 32px tall. The timing bars themselves are 22px tall (centered within the row). Group header rows are 28px tall.
Timing Phase Colors
Section titled “Timing Phase Colors”When Ghost has detailed timing data for a flow (DNS, TCP, TLS, TTFB, Transfer), the bar is segmented — each phase gets a proportional colored segment:
| Phase | Color | What It Measures |
|---|---|---|
| DNS | Emerald | How long it took to look up the domain name (e.g., api.example.com → 192.168.1.1). High DNS times may indicate DNS server issues or cold DNS caches. |
| TCP | Amber | How long the TCP connection took to establish (the “three-way handshake”). High values suggest network latency or congestion. |
| TLS | Purple | How long the TLS/SSL handshake took to negotiate encryption. High values may indicate slow certificate validation or cipher negotiation. |
| TTFB | Cyan | Time To First Byte — how long the server took to start sending the response after receiving the complete request. This is the server’s “thinking time.” |
| Transfer | Blue | How long it took to download the complete response body after the first byte arrived. Proportional to response size and bandwidth. |
Each segment has a minimum width of 1 pixel (if the phase duration is greater than zero), so even very fast phases are visible. All segments render at 70% opacity to prevent visual harshness.
Fallback Colors (No Timing Data)
Section titled “Fallback Colors (No Timing Data)”When detailed timing phases aren’t available (for imported flows, replayed flows, or flows where the proxy couldn’t capture timing breakdown), the bar uses a single color based on the status code:
| Status Range | Bar Style |
|---|---|
| 2xx (success) | Cyan-to-blue gradient |
| 3xx (redirect) | Ghost gray |
| 4xx (client error) | Amber |
| 5xx (server error) | Red |
The minimum bar width is 3 pixels — even sub-millisecond flows are visible (you’d need to zoom in to see their timing, but they’re never invisible).
Duration Labels
Section titled “Duration Labels”When a bar occupies more than 4% of the visible timeline width, a duration label appears inside the bar (e.g., “142ms” or “1.2s”). Labels use a tiny monospace font (9px) in a light color so they’re readable against any bar color. For narrower bars, hover to see the full timing in a tooltip.
Interaction Grouping
Section titled “Interaction Grouping”Flows are automatically organized by browser interaction — each interaction (click, navigation, form submit) becomes a collapsible group header with all its triggered flows beneath it.
How grouping works:
- Flows with an
interactionfield are grouped by{event_type}:{selector}— for example, all flows triggered by a click on#add-to-cartbecome one group - Flows without interactions go into a “Background” group (heartbeats, polling, analytics, etc.)
- Groups are sorted chronologically by the earliest flow’s timestamp
- If there’s only one group and it’s all background traffic, group headers are hidden (flat list)
Group header appearance:
- Click the collapse indicator (triangle ▸/▾) to expand or collapse a group
- Event type badge (purple background with monospace text) — shows “click”, “input”, “navigate”, etc.
- Selector label — the CSS selector of the interacted element, truncated to 30 characters
- Flow count — how many flows are in this group
Diamond markers: Flows that have an associated interaction show a small purple diamond marker (rotated 45-degree square) at the flow’s start position in the bar area, making it easy to spot interaction-triggered requests.
Virtualization
Section titled “Virtualization”The waterfall uses @tanstack/react-virtual for efficient rendering — only the visible rows (plus 20 rows of overscan above and below the viewport) are rendered in the DOM. This means you can view sessions with thousands of flows without any performance degradation. Rows are absolutely positioned using CSS transforms.
Zoom Controls
Section titled “Zoom Controls”Zoom lets you focus on a specific time range within the session.
Ctrl + Scroll wheel (or Cmd + Scroll on macOS):
- Scroll up: zooms in by 0.7x factor (each tick narrows the visible range to 70%)
- Scroll down: zooms out by 1.3x factor (each tick expands the visible range to 130%)
- Zoom is anchored to the cursor position — the point under your cursor stays fixed while the timeline scales around it
- Maximum zoom: 100x (minimum visible span is 1% of the total timeline)
Toolbar buttons (top-right corner):
- Zoom In (magnifying glass +) — halves the visible range, centered on the current midpoint
- Zoom Out (magnifying glass −) — doubles the visible range, centered on the current midpoint
- Reset (arrows out icon) — returns to full timeline view. Only visible when zoomed.
- Zoom indicator — shows current magnification (e.g., “2.5x”) in monospace text. Only visible when zoomed.
Toolbar legend (top-left): Five colored dots with phase labels (DNS, TCP, TLS, TTFB, Transfer) so you always know what the colors mean.
Auto-Reset
Section titled “Auto-Reset”Zoom and collapse state automatically reset when the underlying flow data changes — detected by a fingerprint of {flowCount}:{firstFlowID}. This prevents stale zoom positions when you switch sessions, apply filters, or new traffic arrives.
Row Interaction
Section titled “Row Interaction”- Click a row to select it (highlights with a subtle purple tint). Click again to deselect.
- Hover over a row to see it highlighted with
bg-ghost-850. - The selected flow can be inspected in the flow detail panel alongside the waterfall.
Single-Flow Timing Detail
Section titled “Single-Flow Timing Detail”The per-flow timing view is an overlay in the flow inspector — toggle it with the timer icon in the inspector’s hero bar. It provides deep analysis of one flow’s timing.
Duration Classification
Section titled “Duration Classification”The flow’s total duration is classified with a speed label and color:
| Duration | Label | Color | What It Means |
|---|---|---|---|
| ≤ 0 ms | Pending | Gray | The request hasn’t completed yet or has no timing data |
| < 100 ms | Blazing | Cyan | Extremely fast — typical for cached responses, CDN hits, or localhost |
| < 500 ms | Fast | Green | Good performance — typical for well-optimized API calls |
| < 1,500 ms | Normal | Blue | Acceptable for most operations — typical for database queries or moderate computation |
| < 5,000 ms | Slow | Amber | Noticeable delay — may indicate performance issues worth investigating |
| ≥ 5,000 ms | Very Slow | Red | User-impacting delay — likely a timeout, cold start, or heavy computation |
Visual Duration Bar
Section titled “Visual Duration Bar”A horizontal bar showing this flow’s duration relative to the slowest flow in the session:
- Fill width: proportional to
duration / sessionMax(so the slowest flow always fills 100%) - Fill color: a gradient that shifts with duration — cyan-to-blue for fast flows, cyan-to-purple for normal, purple-to-amber for slow, amber-to-red for very slow
- P50 marker: a thin vertical line (gray, 60% opacity) at the 50th percentile (median) position, with hover label showing the exact P50 value
- P95 marker: a thin vertical line (amber, 60% opacity) at the 95th percentile position, with hover label
- Bottom labels:
0ms,P50: {value},P95: {value},Max: {value}— spanning the full bar width
How percentiles are calculated: All flows in the current store with a duration > 0 are sorted. P50 = value at the 50% position. P95 = value at the 95% position. The current flow’s percentile rank is calculated as the percentage of flows with duration ≤ this flow’s duration. Displayed as “Faster than {100 − percentile}% of flows.”
Timing Breakdown
Section titled “Timing Breakdown”When the flow has detailed timing data, a horizontal stacked bar shows all five phases proportionally:
| Phase | Color | Description |
|---|---|---|
| DNS | Teal | DNS lookup time |
| Connect | Blue | TCP connection time |
| TLS | Purple | TLS handshake time |
| TTFB | Cyan | Time to first byte |
| Transfer | Pink | Data transfer time |
Each segment has a minimum width of 2 pixels and shows a hover tooltip with the phase name and exact duration. Below the bar, a 5-column grid shows each phase with a colored dot, label, and formatted duration.
Transfer Size
Section titled “Transfer Size”When the flow has non-zero content, this section shows:
- Request size bar — cyan-to-blue gradient, width proportional to the larger of request/response
- Response size bar — purple-to-pink gradient, same proportional scaling
- Total — combined size in human-readable format (KB, MB)
- Ratio — response-to-request size ratio (e.g., “1:4.2”), helping identify requests where the response is disproportionately large
Session Context
Section titled “Session Context”Four stat cards showing the current session’s timing profile:
| Stat | What It Shows |
|---|---|
| Average | Mean duration across all flows with timing data |
| P50 | Median duration — half the flows are faster, half are slower |
| P95 | 95th percentile — only 5% of flows are slower than this. Often used as a performance target. |
| Total Flows | Count of flows with timing data (formatted with locale separators, e.g., “1,247”) |
Connection Details
Section titled “Connection Details”A two-column grid showing metadata about the connection:
| Field | What It Shows |
|---|---|
| Started | Formatted timestamp of when the request began |
| Duration | Total request duration |
| Protocol | HTTP protocol version from the request (e.g., HTTP/1.1, HTTP/2) |
| Source | How the flow was captured (proxy, replay, import, script) |
| Host | The target hostname |
| Content Type | Response content type (falls back to request content type, then ---) |
| Status | Response status code and text (only shown if a response exists) |
| Response Proto | HTTP protocol version from the response (only shown if a response exists) |
| Metadata | Any additional flow metadata entries, shown below a separator line |
Session Comparison Timing
Section titled “Session Comparison Timing”When comparing two sessions, Ghost shows a timing diff for matched flows:
| Column | What It Shows |
|---|---|
| Phase | DNS Lookup, TCP Connect, TLS Handshake, TTFB, Transfer, Total |
| Source | Duration in the source session |
| Target | Duration in the target session |
| Delta | Difference (red if > 10ms slower, green if > 10ms faster, gray if within 10ms) |
The phase with the largest absolute delta (if ≥ 50ms) is highlighted as the bottleneck — shown in red bold text to draw attention to where the performance change is concentrated.
Use Cases
Section titled “Use Cases”Identify parallelism opportunities — The waterfall shows which requests happen sequentially vs. in parallel. If five API calls run one-after-another (a “staircase” pattern), you might be able to batch them or run them concurrently.
Find the slow phase — A request took 2 seconds, but was it DNS (change your DNS server), TLS (warm up TLS sessions), TTFB (optimize your backend), or Transfer (compress the response)? The timing breakdown answers this instantly.
Spot waterfall bottlenecks — When Request B can’t start until Request A finishes (because A returns data that B needs), you see a clear sequential pattern. The waterfall makes these dependency chains visible at a glance.
Group by user action — See all the network activity triggered by a single button click. If clicking “Add to Cart” fires 12 requests taking a total of 800ms, the interaction group shows exactly which requests contribute to the perceived delay.
Compare performance across sessions — The timing diff view in session comparison highlights exactly which phases got slower or faster, with the bottleneck automatically identified.
Monitor P95 drift — The single-flow detail view shows where the current request sits relative to the session’s P50 and P95 markers. If a request that was consistently at P50 is now at P95, something changed.