Is it time to check why your code is so slow? Golang provides powerful built-in profiling tools to help identify performance bottlenecks.
Setting up pprof
To enable profiling, add pprof handlers to your HTTP server by importing:
import _ "net/http/pprof"
If you’re using the standard HTTP server, this will automatically register handlers at /debug/pprof/
.
For custom mux routers (like gorilla/mux), you’ll need to register the handlers explicitly:
import (
"net/http"
"net/http/pprof"
)
// Register pprof handlers
router.HandleFunc("/debug/pprof/", pprof.Index)
router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
router.HandleFunc("/debug/pprof/profile", pprof.Profile)
router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
router.HandleFunc("/debug/pprof/trace", pprof.Trace)
Make sure your server is listening on a port (6060 is commonly used for profiling):
http.ListenAndServe(":6060", nil)
Collecting CPU profiles
Run your application, then collect a CPU profile with:
❯ go tool pprof 'http://localhost:6060/debug/pprof/profile?seconds=60'
Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=60
Saved profile in /Users/bx2/pprof/pprof.main.samples.cpu.001.pb.gz
File: main
Type: cpu
Time: Mar 19, 2024 at 8:14pm (CET)
Duration: 60.08s, Total samples = 3.79s ( 6.31%)
Entering interactive mode (type "help" for commands, "o" for options)
The seconds
parameter controls how long the profiling runs. Longer durations provide more accurate results but require your application to be running longer.
Analyzing profiles
Once in the interactive pprof shell, visualize the profile with:
(pprof) web
This opens a browser with a graph visualization showing which functions consume the most CPU time. Functions taking more time appear larger and with darker colors.
Other useful pprof commands include:
(pprof) top # Shows top functions by CPU usage
(pprof) list func # Shows source code with line-by-line profiling data
(pprof) png # Generates a PNG image of the profile
Memory profiling
To inspect memory usage, you can look at heap profiles. Access the memory profile directly in your browser:
http://localhost:6060/debug/pprof/heap?debug=1
Or analyze it with pprof:
go tool pprof http://localhost:6060/debug/pprof/heap
Other profile types
Go’s pprof offers several profile types:
/debug/pprof/profile
- CPU profile/debug/pprof/heap
- Memory allocations/debug/pprof/block
- Goroutine blocking/debug/pprof/mutex
- Mutex contention/debug/pprof/goroutine
- All goroutines/debug/pprof/threadcreate
- OS thread creation
Flame graphs
For a more intuitive visualization, try generating flame graphs:
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile
This starts a local web server where you can switch between different visualization types, including flame graphs.