---
description: Diagnose HTTP performance issues from a lobe capture session. Invoke when the user says their API is slow, mentions lobe, or points at a `/tmp/lobe-capture-session-*.json` file. Applies the (Utilization, Saturation, Errors) methodology with grounded baseline thresholds.
alwaysApply: false
---
# lobe-diagnose
You are analyzing a captured HTTP session produced by the `lobe` tool — a local performance proxy that measures every request's DNS, TCP, TLS, TTFB, and download phases. Your job is to apply the (Utilization, Saturation, Errors) methodology to explain what's slow and what to fix first.
## Step 1 — Locate the session file
Priority order:
1. If the user provided a path, use it.
2. Otherwise, find the most recent capture:
```bash
ls -t /tmp/lobe-capture-session-*.json 2>/dev/null | head -1
```
3. If no capture exists, tell the user to run:
```bash
lobe capture <upstream>
# hit the API, then press `e` in the TUI to export
```
Then re-invoke this rule.
## Step 2 — Understand the file shape
The file is JSON. You care about the `events` array:
```json
{
"version": 1,
"listen_addr": "127.0.0.1:7878",
"upstream": "http://localhost:3000",
"exported_at_ms": 1704000000000,
"event_count": 42,
"events": [
{
"request_host": "localhost",
"request_method": "GET",
"request_path": "/api/users",
"response_status_code": 200,
"response_bytes": 1234,
"report": {
"dns_ms": 0,
"tcp_ms": 1,
"tls_ms": 0,
"ttfb_ms": 45,
"download_ms": 3,
"total_ms": 49
},
"error_message": null,
"created_at_ms": 1704000000000
}
]
}
```
Read only what you need; do not print raw JSON back at the user.
## Step 3 — Apply the (Utilization Saturation Errors) method (this priority order)
### 3a. Utilization (do this first)
Sum `total_ms` per `(method, path)`. Rank routes by **cumulative wall-clock time**, not individual latency. Top of this list is where optimization has the most leverage.
### 3b. Saturation
For each unique `(request_method, request_path)` group:
- Compute **P50, P90, P99** of `report.total_ms`.
- **Long tail**: if `P99 > 5 × P50`, the tail is unusually long.
- **TTFB dominance**: if median `ttfb_ms > 60% of total_ms`, the upstream is doing slow work before it starts writing the response. Most common finding in real captures.
- **Download dominance**: if median `download_ms > 60% of total_ms`, response body is large relative to bandwidth.
- **Bimodal distribution**: sort the total_ms values. If they cluster into two clearly separated bands (e.g., most around 4ms, another cluster around 47ms), flag it as bimodal — classic cache hit vs. miss, or fast-path/slow-path branch.
### 3c. Errors
Count events where `response_status_code` is `null` OR outside `200..=299`. Group by `(status_code, method + path)`. Report the top patterns with counts and share of total requests.
If zero errors: write "No errors observed."
## Step 4 — Cross-check against baseline thresholds
Classify each request's host and compare:
| Host category | Which hosts | TTFB baseline | Total baseline |
|---|---|---|---|
| **loopback** | `localhost`, `127.x.x.x`, `::1` | ≤ 50ms | ≤ 80ms |
| **LAN** | 10.x, 192.168.x, 172.16-31.x, `*.local` | ≤ 100ms | ≤ 200ms |
| **remote** | anything else (public internet) | ≤ 500ms | ≤ 1.5s |
Anything meaningfully over these is worth calling out. A localhost API returning in 340ms is 4× baseline — a big deal. A remote API returning in 340ms is fine.
## Phase interpretation cheatsheet
When a phase is anomalously high, use this to explain *why*:
- **DNS excess** → resolver issue, cold DNS lookup, custom `/etc/hosts` entries
- **TCP excess** → saturated network path or upstream at capacity
- **TLS excess** → old TLS version, deep certificate chain, slow ALPN
- **TTFB excess** → almost always slow DB queries, missing indexes, N+1 queries, or CPU-bound work before writing the response. 80% of real findings.
- **Download excess** → large response body, streaming slowly, or missing compression
## Step 5 — Output format
Return a markdown report with **these exact sections in this order**:
### Summary
2–3 sentences. Lead with the number that matters most.
### Utilization
Which endpoints burn the most cumulative time. Be specific.
### Saturation
Tail behavior, TTFB dominance, bimodal patterns. Cite specific numbers.
### Errors
Top error patterns. If none: "No errors observed."
### Recommendations
Exactly **3–5** specific, actionable items ranked by expected impact. Each item must be concrete.
**Good**: *"Add an index on `users.email`. GET /api/users P99=340ms with TTFB dominating (280ms of 340ms); the endpoint likely does a full-table scan by email."*
**Bad**: *"Look at your database performance."*
## Rules
- **Be concrete**. Cite specific endpoints, specific numbers, specific phase names.
- **Do not fabricate causes**. If the phase breakdown doesn't uniquely point at a root cause, say so.
- **Prioritize wall-clock impact over ratio**. A phase 5× over baseline that adds 3ms matters less than one 2× over that adds 200ms.
- **Do not print the raw session JSON back at the user**.