8 lessons

Distributed Tracing

Where a request spends its time across services. Spans and their relationships, context propagation through queues, the waterfall view, critical-path reasoning, and N+1 as a visible shape.

SymptomSignalMeasurementHypothesisEvidenceRoot CauseChangeValidationRegression Check

Every lesson below starts from an observable symptom and ends with the measurement that proves the fix worked. Numbers carry a label saying whether they were measured, estimated, simulated or invented to show a shape.

Where the Request Actually Went
▶ lab

Metrics tell you the endpoint got slower. A trace tells you which of the eleven things it touched got slower. One request, one timeline, every hop measured — and usually one span holding 80% of the budget that nobody suspected.

Symptom · Checkout "feels slow". The endpoint dashboard confirms p99 rose from 140 ms to 500 ms, and every individual service dashboard looks normal, because no single service owns the request.
Trace, Span, Attribute, Status

A span is a timed operation with a parent, a status and a bag of attributes. Which facts belong in attributes, which belong in span events, and which belong in a metric instead is the difference between a trace you can query and a very expensive log line.

Symptom · The traces exist but nobody queries them: spans are named `handler`, carry either nothing useful or an entire request body, and the one attribute you need to filter by — tenant, route, cache hit — was never recorded.
Parents, Children and Links

Nesting is a claim about causality and containment: a child span asserts its parent was waiting for it. Get that wrong — most often by making a queued job a child of the request that enqueued it — and the waterfall stops describing anything real.

Symptom · A trace whose root span is four minutes long for an endpoint that returns in 80 ms, or child spans that extend past the end of their parent, or an entire background job missing from the trace it obviously belongs to.
Carrying the Trace Across the Gap

Trace context travels in-band with the work: a header on the HTTP call, a field on the queue message, an argument to the job. Every hop that forgets to carry it cuts the trace in half — and the caller looks like it was idle for 400 ms.

Symptom · Traces that stop at a service boundary: the caller has a 400 ms span with no children and no explanation, while somewhere else a second trace starts from nowhere with no idea who caused it.
Reading the Waterfall

Six shapes cover most of what a waterfall can tell you: the staircase, the comb, the fat leaf, the gap, the overhang and the cliff. Learning to recognize them turns trace reading from scrolling into diagnosis.

Symptom · You have the trace open and 40 spans in front of you, and no idea which one is the finding. Everything looks like it takes some time.
The Critical Path Is the Only Path That Pays

In a fan-out, only the slowest branch controls when the request finishes. Optimizing any other branch produces a beautiful graph in your dependency dashboard and zero improvement for users — until the critical path moves, and then a different branch matters.

Symptom · A dependency was optimized from 64 ms to 10 ms, its own dashboard shows a 6× improvement, and end-to-end p99 did not move by a millisecond.
The Comb: N+1 as a Visible Shape

One query to fetch the users, then one query per user to fetch their orders. Every individual query is fast, every dashboard is green, and the endpoint takes 268 ms because it made 101 round trips instead of 2.

Symptom · An endpoint that got slower as data grew, with a database that reports low CPU, fast queries and no slow-query log entries. Latency scales with the number of items on the page.
Sampling Without Throwing Away the Evidence

At 10,000 requests a second, tracing everything is a second production system. Sampling is inevitable; the question is whether you keep a random 1% — which discards almost every slow and failed request — or keep the ones that matter.

Symptom · Either a tracing bill that rivals compute, or — after someone reduced it — an incident where every slow request the customer reported has no trace, because uniform sampling kept the boring ones.