Diagnosing Go memory leaks with pprof heap profiles
production profiling with pprof.
expose net/http/pprof, grab /debug/pprof/heap, analyze inuse_space for live retention versus alloc_space for cumulative allocation; rising inuse over time points to a leak.
WHAT THIS TESTS Whether you can profile a live Go service for memory issues and correctly interpret the difference between retained memory and cumulative allocation to isolate a leak.
A GOOD ANSWER COVERS Import net/http/pprof so it registers handlers under /debug/pprof, and serve it on an admin port. To capture a heap profile, fetch /debug/pprof/heap, or run go tool pprof against that URL directly. The heap profile carries multiple sample types: inuse_space and inuse_objects report bytes and counts still live at the moment of sampling, after the last GC; alloc_space and alloc_objects report the total allocated since the process started, including memory already freed. To diagnose a leak you compare inuse_space over time: take a baseline, let the service run, take another snapshot, and use pprof -base to diff them. A genuine leak appears as inuse_space climbing steadily and never returning, with the stacks pointing at the allocation site that retains references. High alloc_space with stable inuse_space is normal allocation churn, not a leak.
COMMON WRONG ANSWERS Using alloc_space to find leaks; it reflects total allocation rate, so a hot path dominates it even with zero retention. Confusing high allocation with high retention. Forgetting that the heap profile is sampled, so small objects may be under-counted.
LIKELY FOLLOW-UPS How do you read the profile, top, list, and the flame graph in web view? How does the sampling rate MemProfileRate affect accuracy? How do goroutine leaks differ, visible via the goroutine profile? Why force a GC before sampling for cleaner inuse numbers?
ONE CONCRETE EXAMPLE A cache that appends to a global slice without eviction: alloc_space looks ordinary, but diffing two inuse_space snapshots with go tool pprof -base base.pb.gz heap.pb.gz shows inuse climbing, and list on the suspect function points to the append line retaining everything, confirming the leak.
Read the original → pkg.go.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.