pprof
The visualization and analysis tool for profile.proto performance profiles, with interactive, graph, and web-based views.
Repository Health
Technical Analysis
pprof is Google’s tool for visualizing and analyzing profiling data in the profile.proto format — the same wire format produced by Go’s runtime/pprof and net/http/pprof, and now used as a common interchange format across the profiling ecosystem. It reads one or more compressed profile files, or fetches a profile live over HTTP from a running process, and turns raw call-stack samples into text reports, Graphviz-rendered call graphs, or a full interactive web UI with flame graphs and source/disassembly annotation.
Because it operates on the wire format rather than a single language’s runtime, pprof can symbolize and diff profiles from any tool that emits profile.proto, using native binutils integration (addr2line, nm) and multi-language symbol demangling (C++, Rust, Swift) to resolve raw addresses back to function names and source lines.
What You Get
- Three report modes — a
-top-style text report, a Graphviz-rendered SVG call graph, and a full-httpweb UI with flame graphs - Native symbolization via
addr2line/nmand demangling of C++, Rust, and Swift symbols - Support for aggregating and diffing multiple profiles (e.g. before/after comparisons)
- An importable
profileGo package for parsing, encoding, and manipulating profile.proto data programmatically - Support for reading
perf.datafiles (via the companionperf_data_converterproject) alongside native Go profiles
Common Use Cases
- Debugging a CPU hotspot - a Go developer profiles a slow service with
net/http/pprof, then runspprof -topagainst the captured profile to find the hottest call stacks - Comparing before/after performance - an engineer profiles the same workload before and after a change and uses pprof’s diff mode to see which functions regressed
- Visualizing memory allocation - a team investigating a memory leak generates an
-httpflame graph from a heap profile to see which allocation paths dominate - Building custom profiling tooling - a platform team imports the
profilepackage directly to parse, filter, and re-encode profile.proto data as part of an internal continuous-profiling pipeline
Under The Hood
Architecture
The main package (pprof.go) wires a readline-backed terminal UI into driver.PProf (driver/driver.go), a thin public wrapper around the real engine in internal/driver. That internal package dispatches to an interactive shell, a static report renderer, or the embedded web UI (internal/driver/webui.go plus the html/ templates and third_party/svgpan) depending on the flags passed. Supporting internal packages handle native symbolization (internal/binutils, internal/elfexec, internal/symbolizer, internal/symbolz), graph construction and rendering (internal/graph, internal/report), and unit handling (internal/measurement) — kept unexported so the engine can evolve freely behind the two stable public entry points, profile and driver. The profile.Profile struct is the central in-memory model threaded through every stage of the pipeline, so a change to its shape would ripple through symbolization, filtering, and every report-rendering path.
Tech Stack
A Go module (go 1.25) with a deliberately small dependency surface: github.com/chzyer/readline for the interactive shell, github.com/ianlancetaylor/demangle for C++/Rust/Swift symbol demangling, and golang.org/x/sys as an indirect dependency. The -http mode is a plain net/http server serving embedded HTML/JS/CSS assets rather than a web framework, and it shells out to Graphviz’s dot plus binutils’ addr2line/nm for graph rendering and address symbolization. Profile data itself is protocol-buffer-encoded per proto/profile.proto, decoded through the profile package’s own hand-written encode/decode rather than the standard protobuf runtime. It ships as a single static binary via go install, with a GitHub Actions CI matrix (ci.yaml) exercising multiple Go versions across macOS, Linux, and Windows.
Code Quality
An extensive test suite — over thirty _test.go files — covers the profile package (encoding round-trips, merging, filtering, pruning, legacy-format decoding) and internal/driver (command dispatch, interactive mode, the web UI, HTTP fetching), plus a dedicated fuzz corpus for profile decoding. Errors are returned explicitly as Go error values throughout rather than panicking, and naming follows standard Go conventions. There’s no dedicated linter config checked in, but the CI matrix runs the full test suite across multiple Go versions and operating systems on every push and nightly.
What Makes It Unique pprof’s distinguishing choice is being both the reference implementation of the profile.proto wire format — adopted well beyond Go as a de facto interchange format for continuous-profiling systems — and a fully interactive analysis tool with three complementary UI modes built around one shared in-memory model: a readline shell, static Graphviz-rendered graphs, and a built-in web UI with flame graphs, source annotation, and diff-between-profiles views. Its native symbolization support, including addr2line/nm integration and multi-language demangling, sets it apart from profilers that only resolve symbols within their own language runtime.
Used by 4 apps in this directory
Coroot
Analytics · Monitoring
eBPF-powered observability with AI root cause analysis — zero code changes required, full-stack visibility out of the box.
Gitea
Devops · Developer Tools · Project Management
Self-hosted DevOps in a single Go binary — Git hosting, GitHub Actions-compatible CI/CD, and 30+ package registries without any SaaS dependency.
Pyroscope
Monitoring · Devops · Developer Tools
An open-source, horizontally scalable continuous profiling platform that pinpoints CPU, memory, and I/O bottlenecks down to the exact line of code, built by Grafana Labs alongside Loki, Tempo, and Mimir.
TiDB
Databases · AI Development
AI-Native Distributed SQL Database for Agentic Workloads