Share a pprof profile

go tool pprof -http=:8080 cpu.pprof is one of the best profiling experiences in any language, and it has exactly one flaw: it runs on localhost. The moment the finding needs a second reader, the interface degrades to a screenshot of a flame graph, which is a picture of a thing whose entire value is that you can click it.

Option 1: an SVG flame graph

# apt-get install graphviz  (pprof shells out to dot)
go tool pprof -svg cpu.pprof > cpu.svg

The SVG is self-contained and keeps click-to-zoom and hover tooltips, because the script travels inside the file. Wrap it in a one-line HTML host if you want a title above it, or publish the SVG as the report body.

Option 2: speedscope

npm i -g speedscope
speedscope cpu.pprof   # opens locally; use the app's Export to save an HTML file

Speedscope reads pprof's protobuf format directly and its exported page keeps the time-order view, the left-heavy view, the sandwich view and search. It is the better option when the reader needs to explore rather than confirm. See also sharing a speedscope profile.

Publish it

Drag the file into the app, or from CI:

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html cpu.html \
        --arg title "CPU profile — $GITHUB_SHA" '{title: $title, html: $html}')"

Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the zooming works at the URL the same way it worked locally.

Profiles from production

curl -o cpu.pprof "http://prod-host:6060/debug/pprof/profile?seconds=30"

Two things follow from that. First, render and publish rather than passing around the raw .pprof — the raw file needs the reader to have Go installed and the matching binary for symbolisation. Second, restrict the access level: a profile enumerates your internal package and function names. See the sharing model.

Why the link beats the screenshot

  • Anchored threads on the hot frame, so the fix is discussed where the cost is visible. See commenting on HTML.
  • Revisions — publish before and after the optimisation to the same id and the improvement is a diff, not an assertion.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total. A deep profile's SVG can be large — -nodecount trims it for the shareable view.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a profile →

Related