This is documentation for the next version of Grafana documentation. For the latest stable release, go to the latest version.
Compare profiles with gcx
You can compare profiles with gcx:
- Use
gcx profiles queryfor one profile. - Use
gcx profiles difffor symbol costs across selectors, time windows, or both.diffuses Pyroscope’s server-side comparison, not independently truncated top-function lists.
Follow these steps to compare profiles:
- Configure a Grafana context with read access to Pyroscope.
- Find the datasource UID with
gcx datasources list --type pyroscope. - Find the profile type with
gcx profiles list-profile-types -d <datasource-uid>. - Run then following commands to compare:
gcx profiles diff '{service_name="frontend",version="v1"}' '{service_name="frontend",version="v2"}' \
-d <datasource-uid> --profile-type process_cpu:cpu:nanoseconds:cpu:nanoseconds \
--before-from now-1h --before-to now \
--after-from now-1h --after-to now --drilldown-linkIn this example, both sides share a datasource and profile type. Repeat the same selector to compare different windows. Unsupported selectors warn and fall back without dropping scope.
Use fixed timestamps for reproducible evidence. All four bounds are required: RFC3339, Unix seconds, or relative times. They use one clock snapshot and resolve to whole seconds to match Drilldown.
Dedicated comparisons require the same exact service_name. Names requiring string escaping fall back to Explore, while other matchers are preserved separately.
For a profile UUID from exemplars, add --profile-id <uuid> --drilldown-link to gcx profiles query. A single ID opens the scoped flame graph and multiple IDs or stacktrace selectors fall back to Explore. Trace-ID-scoped queries suppress links because neither UI can preserve their scope.
Interpret costs
Table-wide output shows the top 20 absolute self-cost changes.
JSON, YAML, and agents output retain all returned symbols, warnings, selections, units, and links. The backend node budget defaults to 50,000 in every format.
Take into account the following to interpret costs:
- Costs use the profile type’s raw sample unit.
- Recursive inclusive costs count only the outermost occurrence per stack.
selfattributes cost directly to a function.totalincludes callees.deltais after minus before, without duration or traffic normalization.- Prefer comparable, equal-length windows: traffic, replicas, and sampling can change cost without a regression.
changePercentis null for zero baselines or when either profile has no positive samples. Missing samples do not establish zero cost or improvement.complete=falsemeans frames were folded intoother;omittedreports their costs.- Raise
--max-nodesor narrow selectors to improve attribution. - Absence from a pruned graph does not establish an added or removed function.
Share evidence
To share evidence:
links.beforeandlinks.afteropen individual profiles.links.exploreopens before on the left and after on the right, with independent ranges.links.comparisonopens the dedicated diff view when representable.
The following options are available:
--share-link/--open: print or open split Explore.--drilldown-link/--open-drilldown: print or open Profiles Drilldown. You must enable Drilldown, since URLs target its Scenes contract used in version 3.1.0. Use Explore for older apps that don’t support that contract.


