PGO and Production Build Flags
PGO and Production Build Flags
Overview
Profile-guided optimization (PGO) feeds CPU profiles into the compiler for better inlining/layout on hot paths. Combine with production build flags for smaller, clearer binaries.
Production build baseline
CGO_ENABLED=0 go build -trimpath \
-ldflags="-s -w -X main.version=${VERSION}" \
-o bin/app ./cmd/app| Flag | Effect |
|---|---|
CGO_ENABLED=0 |
Static-ish pure Go, portable |
-trimpath |
Reproducible paths |
-s -w |
Strip symbol/DWARF (harder debug) |
-X |
Inject version |
Keep a debug build variant for crash analysis when needed.
PGO workflow (Go 1.20+)
# 1) collect profile from realistic load (30s+)
curl -o cpu.pprof "http://localhost:6060/debug/pprof/cpu?seconds=30"
# 2) rebuild with profile
go build -pgo=cpu.pprof -o bin/app ./cmd/app
# 3) compare benchmarks / load testOr default auto PGO if default.pgo is in the main package directory (per Go release docs).
When PGO helps
| Helps | Less impact |
|---|---|
| Large codebases, hot call chains | Tiny programs already inlined |
| After stable production shape | Random microbench only |
Rules of thumb
| Do | Don’t |
|---|---|
| Profile production-like traffic | Use toy profiles for PGO |
| A/B load test before/after | Assume free wins always |
| Document Go version + flags | Mystery binaries in prod |
Try next
- Capture 30s CPU pprof under
hey.
- Build with
-pgoand remeasure p99.
- Add version ldflags; verify
app version.