Trace ↔ Profile Correlation
This tutorial shows how to correlate OpenTelemetry trace spans with Pyroscope continuous profiles by injecting the root trace and span identifiers into Pyroscope tags.
Why Correlate?
When a latency spike appears in tracing (Tempo), you want to jump directly into the CPU or allocation profile that was active during that span. By adding trace_id (and an optional root_span_id) tags to Pyroscope profiles you gain:
- Direct filtering in Pyroscope for a problematic trace
- Time-aligned hotspot analysis for that execution
- Unified incident narrative (single IDs across logs, traces, profiles)
Enabling Correlation
Set the environment variable before running the Pyroscope-enabled binaries:
PYROSCOPE_TRACE_CORRELATION=true PYROSCOPE_SERVER_ADDRESS=http://localhost:4040 \
PYROSCOPE_TAGS="env=dev,service=generator" \
./generator-grafana-pyroscope 50000 out.json
When enabled the binary:
- Starts a lightweight root span (
generator.runorloader.run) - Extracts
trace_idandspan_id - Appends them to
PYROSCOPE_TAGS(once) astrace_id=<id>,root_span_id=<id> - Profiles uploaded to Pyroscope now carry those IDs
You’ll see the enhanced tags in Pyroscope’s label selector.
Querying in Pyroscope
- Open Pyroscope UI → Select the application name (e.g.
interviewing-golang.generator) - Add a tag filter:
trace_id=<value> - Compare flamegraph of that trace vs baseline (remove
trace_idfilter)
Trace to Profile Workflow
- In Grafana Tempo, locate a slow trace
- Copy its
Trace ID - Paste as a tag filter in Pyroscope
- Analyze top frames unique to that trace
Overhead Considerations
- Only a single root span is created (no per-event spans) to keep correlation overhead negligible.
- Tag cardinality impact: one additional value per execution. Safe for short-lived batch jobs and low-frequency tasks.
- Disable by unsetting
PYROSCOPE_TRACE_CORRELATION.
Advanced: Enforcing Tag Structure
If you already use PYROSCOPE_TAGS, the correlation logic appends missing keys without overwriting existing ones. Example final tag string:
env=dev,service=generator,version=1.0.0,trace_id=abcd1234...,root_span_id=ef567890...
Future Extensions
| Goal | Approach |
|---|---|
| Span-level profiling windows | Embed span timestamps; query narrower ranges |
| Multi-span correlation | Export span events referencing profile slice IDs |
| UI deep link | Construct Grafana Tempo URL from trace_id & add link in docs |
Correlating traces and profiles shortens mean time to insight by combining structural (trace) and cost (profile) perspectives of the same execution.