What is Profile-Guided Optimization (PGO) in Go, and how do you use it?
Question 387HardGo 1.22 to 1.25
PGO (GA in Go 1.21) feeds a CPU profile from production into the compiler so it optimizes hot paths more aggressively. The Go team reports typical gains of 2–14% CPU.
Workflow:
# 1. collect a representative CPU pprof from production
curl -o cpu.pprof 'http://127.0.0.1:6060/debug/pprof/profile?seconds=30'
# 2. place it in the main package directory
mv cpu.pprof ./cmd/server/default.pgo
# 3. build normally — -pgo=auto is the default and picks up default.pgo
go build ./cmd/server
# explicit / merged profiles:
go tool pprof -proto a.pprof b.pprof > merged.pprof
go build -pgo=merged.pprof ./cmd/server
What it does today:
- Hot-call inlining: call sites that are hot in the profile get a much larger inlining budget than the normal ~80 nodes.
- Devirtualization: a hot interface call whose dynamic type is usually
*Tgets a guarded direct call (if x, ok := i.(*T); ok { x.M() } else { i.M() }), which can then be inlined. - Layout/register improvements continue to be added.
Gotchas: commit the profile to the repo so builds are reproducible; stale profiles from older code still work (matching is by function name + line offset) but degrade gracefully; build time and binary size grow modestly; it's iterative-stable (building with PGO then re-profiling doesn't oscillate). Profile representative traffic — a profile from a load test that exercises the wrong path helps the wrong code.
More on Performance, Profiling & Testing
- Q385How do you test HTTP handlers and HTTP clients with net/http/httptest?
- Q386How does test coverage work in Go? Explain covermode, -coverpkg, and coverage for integration tests.
- Q388How does inlining work in the Go compiler, how do you inspect it, and what prevents a function from being inlined?
- Q389Explain escape analysis. Which of these allocate on the heap?
- Q390What is bounds check elimination (BCE), how do you see it, and how can you help the compiler?
- Q391What are the tradeoffs of sync.Pool? When does it help, and when does it hurt?