# Trace Desk > Diagnose one distributed trace exported from Jaeger, Zipkin, Grafana Tempo or an OpenTelemetry collector. The free check runs in the browser and uploads nothing: the span tree and a waterfall, each span's self time, the critical path and each span's and service's share of it, N+1 loops, repeated and slow queries, serial calls, retries, error origins, uninstrumented time, lost context propagation, clock skew and orphan spans. The paid diagnosis names the pattern, the bottlenecks, root-cause hypotheses with checks, fixes with an upper bound on what each saves, and the instrumentation to add, and the page checks every span id, share and saving against the trace. App: https://trace-desk.skillsafe.ai/ API tutorial: https://trace-desk.skillsafe.ai/api.html ## Formats read - Jaeger JSON: the UI's "Download JSON" and /api/traces responses ({"data":[{traceID, spans, processes}]}), CHILD_OF and FOLLOWS_FROM references, tags and logs. - Zipkin v2 JSON: an array of spans, or an array of traces. Shared client/server spans (B3, one span id for both halves of an RPC) are split so the server half hangs under the client half. - OTLP/JSON: resourceSpans or Tempo's batches, scopeSpans or instrumentationLibrarySpans, JSON Lines from the collector file exporter, and the Jaeger v3 API's {"result":{resourceSpans}}. Ids in hex or protobuf-JSON base64; nanosecond timestamps are cut to microseconds on the string so they keep their precision. - An export with several traces: the one with the most spans is analysed. ## What the free check computes - Self time: a span's duration minus the union of its children's intervals clipped to the span. - The critical path, walked back from the end of the root span: at each moment the request waits on the child that finished last before that moment; the time between children belongs to the parent. Children are clipped to their parent's window, so skewed clocks cannot inflate it, and the shares add up to the request's latency. A span's subtree critical time bounds what removing or speeding up that call can save. - Per service: spans, critical-path time and share, own work, errors. - N01 N+1: five or more calls under one parent with the same service, operation (digits, UUIDs and hex normalised) and query shape, whose summed duration is at least 80% sequential. N02: ten or more of them in parallel. Their critical share includes everything under them. - Q01: a query shape (literals, numbers and $n placeholders replaced by ?) run three or more times; Q02: a database span over 25% of the request and 50 ms. - P01: a parent over 20% of the request whose outgoing calls to three or more different operations do not overlap and take at least half its time. - E01 error spans (OTel status ERROR, error tags, HTTP 5xx) and the deepest ones, E02 a failed root span, E03 the same call repeated after an error. - D01 one span's own work over 40% of the request; D02 one service over 60% of the critical path. - G01 a span with children whose own time is over half of it and over 20% of the request; G02 an outgoing client call over 5% of the request with no downstream span; G03 missing service names; G04 HTTP spans without a status code; G05 zero-length spans. - K01 orphans, K02 several roots, K03 a synchronous child starting over 1 ms before its parent, K04 one ending over 1 ms after it, K05 duplicate ids. - Shares of a request under 50 ms are not flagged for dominance, gaps, slow queries or serial calls. - Exports: the check as Markdown and every span as CSV (spreadsheet formula characters are escaped). - Before and after: keep one check as a baseline (or pick a past diagnosis), paste the export from after a change, and see latency, error spans, each service's critical-path time and which flags went away or appeared. One trace each side, so it is a first read, not a p95. - Each fix in a diagnosis copies as a ticket body: title, priority, the span, the most it can save, the bottleneck it addresses and the check for the likely cause. ## The paid diagnosis Input: {"task": "diagnose", "facts": "", "note": "optional"}. The facts are the computed check plus a listing of up to 90 spans chosen by relevance (critical path, errors, flagged spans, largest self times and their ancestors); the raw export is never sent. Output: one JSON object with pattern (n_plus_one, latency_bottleneck, serial_calls, error_propagation, uninstrumented_gap, clock_or_data_issue, healthy), secondary_patterns, confidence, headline, critical_path (reading, dominant_span, dominant_service), bottlenecks (span, service, operation, kind, share_pct, finding, flags), errors (origin, reading), root_causes (hypothesis, span, likelihood, evidence, check), fixes (priority, area, span, change, expected_gain_ms), instrumentation (gap, span, fix), questions and summary. The page checks that every span id exists, the dominant span and first bottleneck are on the critical path, every share matches within 2.5 points, no saving exceeds the critical time of what it changes, the error origin is an error span, a failed request is diagnosed as error propagation, and every high flag is addressed. Runs on the gpt-terra model alias and costs credits; the free check does not. ## What it does not do It reads one trace. It does not query Jaeger, Tempo or any backend, see your code, logs or metrics, or compare against a baseline, and a single trace cannot show a percentile. Clock skew between hosts limits how far sub-millisecond timings can be trusted. ## Sources - OpenTelemetry trace data model and semantic conventions: https://opentelemetry.io/docs/specs/otel/trace/api/ and https://opentelemetry.io/docs/specs/semconv/ - OTLP/JSON encoding: https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding - Jaeger JSON model: https://www.jaegertracing.io/docs/latest/apis/ - Zipkin v2 API and shared spans: https://zipkin.io/zipkin-api/ - W3C Trace Context: https://www.w3.org/TR/trace-context/ - Critical path analysis in Jaeger's trace view: https://github.com/jaegertracing/jaeger-ui - Source skill: distributed-tracing by wshobson, MIT - https://skillsafe.ai/skill/@wshobson/distributed-tracing and https://github.com/wshobson/agents (plugins/observability-monitoring/skills/distributed-tracing)