Runtime and memory · 3 MIN READ
Find a leak by following evidence
Choose a heap profile, goroutine profile, CPU profile or trace to test a specific hypothesis.
A rising memory graph is a symptom. Before changing code, ask whether traffic grew, objects are retained, workers are stuck, or allocation churn became expensive. Different diagnostic tools answer different questions.
Choose the observation
A heap profile helps find retained allocations; allocation profiles emphasize cumulative allocation traffic. A goroutine profile shows where tasks wait. CPU sampling identifies code consuming CPU, while an execution trace exposes scheduling and blocking relationships. Compare the same workload and interval rather than comparing unrelated snapshots.
Write a bounded diagnostic capture
For a native local program, a goroutine profile can be written to a file without opening an HTTP diagnostics server. Handle the file error and close the file. Profiles can include operational details, so store and share them deliberately.
f, err := os.Create("goroutines.txt")
if err != nil {
return err
}
defer f.Close()
if err := pprof.Lookup("goroutine").WriteTo(f, 1); err != nil {
return err
}This fragment belongs inside an error-returning diagnostic function and imports os and runtime/pprof. Capture once at the relevant time; do not create an unbounded stream of profile files.
Turn a suspicion into a comparison
If goroutine count grows after requests finish, compare stacks and identify the owner of the repeated wait. If heap grows with cache keys, inspect eviction and reference lifetimes. Change one thing and repeat the workload. A single stable run does not prove absence of races or leaks, and profiling overhead itself should be considered.
TAKE THIS WITH YOU
Name the hypothesis, choose a tool that can observe it, and compare equivalent workloads before and after the change.
Check your understanding
Which statement is correct about a goroutine profile?
Go to the source
Progress stays in this browser. No account needed.