Go pprof Profiling
Go pprof commands and practices for analyzing CPU, memory, goroutine, and block profiles.
Enable Profiling
HTTP Server
1package main
2
3import (
4 "log"
5 "net/http"
6 _ "net/http/pprof" // Import for side effects
7)
8
9func main() {
10 // Your application code here
11
12 // Start pprof server
13 go func() {
14 log.Println("pprof server starting on :6060")
15 log.Println(http.ListenAndServe("localhost:6060", nil))
16 }()
17
18 // Your main application logic
19 select {}
20}
Programmatic Profiling
1package main
2
3import (
4 "os"
5 "runtime"
6 "runtime/pprof"
7)
8
9func main() {
10 // CPU profiling
11 f, _ := os.Create("cpu.prof")
12 defer f.Close()
13 pprof.StartCPUProfile(f)
14 defer pprof.StopCPUProfile()
15
16 // Your code here
17 doWork()
18
19 // Memory profiling
20 mf, _ := os.Create("mem.prof")
21 defer mf.Close()
22 runtime.GC() // Get up-to-date statistics
23 pprof.WriteHeapProfile(mf)
24}
CPU Profiling
Capture CPU Profile
1# Via HTTP endpoint (30 seconds)
2curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
3
4# Via test
5go test -cpuprofile=cpu.prof -bench=.
6
7# Via runtime/pprof (programmatic)
8# See code example above
Analyze CPU Profile
1# Interactive mode
2go tool pprof cpu.prof
3
4# Commands in interactive mode:
5# top - Show top functions by CPU time
6# top10 - Show top 10 functions
7# list main - Show source code for main package
8# web - Open graphviz visualization (requires graphviz)
9# pdf - Generate PDF report
10# svg - Generate SVG visualization
11# exit - Exit
12
13# Direct commands
14go tool pprof -top cpu.prof
15go tool pprof -list=main cpu.prof
16go tool pprof -web cpu.prof
17
18# Compare two profiles
19go tool pprof -base=old.prof new.prof
20
21# Generate flame graph
22go tool pprof -http=:8080 cpu.prof
Memory Profiling
Capture Memory Profile
1# Heap profile via HTTP
2curl http://localhost:6060/debug/pprof/heap > heap.prof
3
4# Allocs profile (all allocations, not just in-use)
5curl http://localhost:6060/debug/pprof/allocs > allocs.prof
6
7# Via test
8go test -memprofile=mem.prof -bench=.
9
10# Via benchmark with allocation stats
11go test -benchmem -bench=.
Analyze Memory Profile
1# Interactive mode
2go tool pprof heap.prof
3
4# Show allocations
5go tool pprof -alloc_space heap.prof
6
7# Show in-use memory
8go tool pprof -inuse_space heap.prof
9
10# Top allocators
11go tool pprof -top heap.prof
12
13# List specific function
14go tool pprof -list=functionName heap.prof
15
16# Web visualization
17go tool pprof -http=:8080 heap.prof
18
19# Compare profiles
20go tool pprof -base=old_heap.prof new_heap.prof
Goroutine Profiling
Capture Goroutine Profile
1# Via HTTP
2curl http://localhost:6060/debug/pprof/goroutine > goroutine.prof
3
4# Full goroutine stack dump
5curl http://localhost:6060/debug/pprof/goroutine?debug=2 > goroutine.txt
Analyze Goroutines
1# Interactive
2go tool pprof goroutine.prof
3
4# Direct view
5go tool pprof -top goroutine.prof
6
7# Web view
8go tool pprof -http=:8080 goroutine.prof
9
10# Text dump (human-readable)
11cat goroutine.txt
Block Profiling
Enable Block Profiling
1package main
2
3import (
4 "runtime"
5)
6
7func main() {
8 // Enable block profiling
9 runtime.SetBlockProfileRate(1) // 1 = record every blocking event
10
11 // Your code
12}
Capture and Analyze
1# Via HTTP
2curl http://localhost:6060/debug/pprof/block > block.prof
3
4# Analyze
5go tool pprof block.prof
6go tool pprof -top block.prof
7go tool pprof -http=:8080 block.prof
Mutex Profiling
Enable Mutex Profiling
1package main
2
3import (
4 "runtime"
5)
6
7func main() {
8 // Enable mutex profiling
9 runtime.SetMutexProfileFraction(1) // Sample 1 in N mutex events
10
11 // Your code
12}
Capture and Analyze
1# Via HTTP
2curl http://localhost:6060/debug/pprof/mutex > mutex.prof
3
4# Analyze
5go tool pprof mutex.prof
6go tool pprof -http=:8080 mutex.prof
Trace Profiling
Capture Trace
1package main
2
3import (
4 "os"
5 "runtime/trace"
6)
7
8func main() {
9 f, _ := os.Create("trace.out")
10 defer f.Close()
11
12 trace.Start(f)
13 defer trace.Stop()
14
15 // Your code
16 doWork()
17}
1# Via HTTP (5 seconds)
2curl http://localhost:6060/debug/pprof/trace?seconds=5 > trace.out
3
4# Via test
5go test -trace=trace.out
Analyze Trace
1# Open trace viewer
2go tool trace trace.out
3
4# This opens a web browser with:
5# - View trace: Timeline of goroutines
6# - Goroutine analysis: Goroutine execution stats
7# - Network blocking profile
8# - Synchronization blocking profile
9# - Syscall blocking profile
10# - Scheduler latency profile
Benchmarking with Profiling
1# CPU profile
2go test -bench=. -cpuprofile=cpu.prof
3
4# Memory profile
5go test -bench=. -memprofile=mem.prof
6
7# Both
8go test -bench=. -cpuprofile=cpu.prof -memprofile=mem.prof
9
10# With allocation stats
11go test -bench=. -benchmem
12
13# Specific benchmark
14go test -bench=BenchmarkMyFunc -cpuprofile=cpu.prof
15
16# Run longer for more accurate results
17go test -bench=. -benchtime=10s -cpuprofile=cpu.prof
pprof Commands Reference
Top-level Commands
1# top [N] - Show top N entries (default 10)
2# list <regex> - Show source code for functions matching regex
3# web - Open graphviz visualization
4# weblist <regex> - Show annotated source in browser
5# pdf - Generate PDF report
6# svg - Generate SVG
7# png - Generate PNG
8# gif - Generate GIF
9# dot - Generate DOT file
10# tree - Show call tree
11# peek <regex> - Show callers and callees
12# disasm <regex> - Show disassembly
13# exit/quit - Exit pprof
Options
1# -flat - Sort by flat (self) time
2# -cum - Sort by cumulative time
3# -alloc_space - Show allocation space
4# -alloc_objects - Show allocation count
5# -inuse_space - Show in-use space
6# -inuse_objects - Show in-use object count
7# -base <file> - Compare against base profile
8# -http=:8080 - Start web interface
Continuous Profiling
Automated Collection
1package main
2
3import (
4 "fmt"
5 "os"
6 "runtime/pprof"
7 "time"
8)
9
10func collectProfiles() {
11 ticker := time.NewTicker(5 * time.Minute)
12 defer ticker.Stop()
13
14 for range ticker.C {
15 timestamp := time.Now().Format("20060102-150405")
16
17 // CPU profile
18 cpuFile, _ := os.Create(fmt.Sprintf("cpu-%s.prof", timestamp))
19 pprof.StartCPUProfile(cpuFile)
20 time.Sleep(30 * time.Second)
21 pprof.StopCPUProfile()
22 cpuFile.Close()
23
24 // Heap profile
25 heapFile, _ := os.Create(fmt.Sprintf("heap-%s.prof", timestamp))
26 pprof.WriteHeapProfile(heapFile)
27 heapFile.Close()
28 }
29}
30
31func main() {
32 go collectProfiles()
33
34 // Your application
35}
Best Practices
- Profile in production-like environment - Dev machines may not reflect production
- Run long enough - At least 30 seconds for CPU profiling
- Use benchmarks - For repeatable profiling
- Compare profiles - Use
-baseto see improvements - Focus on hot paths - Optimize top functions first
- Profile before optimizing - Don't guess, measure
- Check allocations - Use
-benchmemto see allocation impact - Use trace for concurrency - Better than pprof for goroutine issues
Example Workflow
1# 1. Write benchmark
2cat > main_test.go <<EOF
3package main
4
5import "testing"
6
7func BenchmarkMyFunc(b *testing.B) {
8 for i := 0; i < b.N; i++ {
9 MyFunc()
10 }
11}
12EOF
13
14# 2. Run benchmark with profiling
15go test -bench=. -cpuprofile=cpu.prof -memprofile=mem.prof -benchmem
16
17# 3. Analyze CPU profile
18go tool pprof -http=:8080 cpu.prof
19
20# 4. Analyze memory profile
21go tool pprof -http=:8081 mem.prof
22
23# 5. Make optimizations
24
25# 6. Run again and compare
26go test -bench=. -cpuprofile=cpu_new.prof
27go tool pprof -base=cpu.prof cpu_new.prof
Related Snippets
- Cobra CLI Framework
Building CLI applications with Cobra in Go - Go Authentication Middleware
Authentication and authorization middleware patterns for Go web applications. … - Go Project Structure
Standard Go project layout and organization