Introduction to pprof
The net/http/pprof
package automatically exposes Go runtime profiling data via an HTTP server.
This allows you to inspect the runtime behavior of your Go program in production or development environments.
It's a powerful tool for diagnosing performance bottlenecks, memory leaks, goroutine leaks, and deadlocks.
To enable pprof in your application, you typically need to import the package and start an HTTP server that listens on a specific port.
Enabling pprof
Simply importing the package is enough to register the necessary HTTP handlers. You then need to start an HTTP server to expose these endpoints.
package main
import (
"log"
"net/http"
_ "net/http/pprof" // Import this package to register the handlers
)
func main() {
// Start a separate HTTP server for profiling
go func() {
log.Println("Starting pprof server on :6060")
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatalf("Failed to start pprof server: %v", err)
}
}()
// Your main application logic here...
log.Println("Your main application is running.")
select {} // Block forever
}
Once your application is running with this setup, you can access the profiling data through the following endpoints on port 6060 (or whichever port you choose).
Available Profiling Endpoints
The net/http/pprof
package registers several endpoints under the /debug/pprof/
path. Here are the most commonly used ones:
CPU Profiling
This profile shows CPU time spent in various functions. You can request a profile of a specific duration (in seconds).
/debug/pprof/profile?seconds=30
This will generate a CPU profile for 30 seconds. The output is in a format that can be visualized using the go tool pprof
command.
Heap Profiling
This profile shows memory allocations. It can help identify memory leaks.
/debug/pprof/heap
This endpoint provides a snapshot of the current heap usage.
Goroutine Profiling
This profile lists all goroutines and their stack traces. It's invaluable for diagnosing goroutine leaks or deadlocks.
/debug/pprof/goroutine?debug=2
The debug=2
parameter provides more detailed stack trace information.
Block Profiling
This profile tracks time spent blocked waiting for synchronization primitives.
/debug/pprof/block
Mutex Profiling
This profile tracks contention on mutexes. You need to enable mutex profiling explicitly for your application to collect this data.
/debug/pprof/mutex
To enable mutex profiling, call runtime.SetMutexProfileFraction(n)
. A common value for n
is 1 (e.g., runtime.SetMutexProfileFraction(1)
), which means 1 in every 1 mutex contention event is reported.
Thread Creation Profiling
This profile tracks thread creation events.
/debug/pprof/threadcreate
All Goroutines (Command Line Interface)
This endpoint shows all goroutines and their stack traces, suitable for direct inspection or piping to go tool pprof
.
/debug/pprof/allgoroutines
Index Page
The root of the pprof path itself provides a helpful index page listing available profiles and links to them.
/debug/pprof/
Using go tool pprof
While the HTTP endpoints are useful for quick checks, the go tool pprof
command provides a more powerful
interactive environment for analyzing profile data.
Analyzing CPU Profile
To analyze a CPU profile, you can fetch it directly from the running server:
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
Once in the pprof
interactive shell, you can use commands like:
top
: Show the top functions by cumulative time.list functionName
: Show source code lines for a specific function.web
: Generate a call graph visualization (requires Graphviz to be installed).svg functionName
: Generate an SVG graph of a function.peek functionName
: Show call sites and callers of a function.help
: Display help for pprof commands.
Analyzing Heap Profile
Similarly, for heap profiles:
go tool pprof http://localhost:6060/debug/pprof/heap
The commands available in heap profiling are similar to CPU profiling, focusing on memory usage rather than CPU time.
Analyzing Goroutine Profile
go tool pprof http://localhost:6060/debug/pprof/goroutine
This is particularly useful for understanding where goroutines are being created or stuck.
Important Considerations
- Security: Never expose the pprof endpoints to the public internet without proper authentication and authorization. They can reveal sensitive information about your application's internal state and potentially be used for denial-of-service attacks. Use it judiciously, perhaps behind a firewall or with API gateways.
- Performance Overhead: Profiling adds some overhead to your application. While generally small, it's worth considering, especially in extremely performance-sensitive scenarios. Enable profiling only when needed for diagnostics.
- Context: Always consider the context when analyzing profiles. A high CPU usage in a particular function might be expected if that function is performing intensive computations. The goal is to identify unexpected or excessive resource consumption.
- Runtime vs. Compile-time: pprof profiles runtime behavior. For compile-time optimizations, you would look at other tools.