Menu

1 / 2

Goroutine Leaks Don't Show Up in CPU Profiles. Here's What to Read Instead

DEV Community·Gabriel Anhaia·6 months ago
#IG25sCE1
#go#debugging#performance#pprof#goroutine
Reading 0:00
15s threshold

Book: The Complete Guide to Go Programming

Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go

My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools

Me: xgabriel.com | GitHub

You're staring at a CPU profile from a service that's eating 12GB of RAM and getting OOM-killed every four hours. Top function on the flame graph is runtime.gcBgMarkWorker . Below it, runtime.scanobject . Below that, your handler code, taking 1.4% of samples. Nothing else looks suspicious. The hot path is genuinely hot, but it's the hot path you've already tuned.

You scroll up. You scroll down. You re-record the profile twice. The flame graph keeps telling you the service is fine.

The flame graph is right. The service is also leaking goroutines.

CPU profiles measure work. A parked goroutine does no work. It sits on a channel receive, a select with no ready clauses, a WaitGroup.Wait , or a sync.Mutex.Lock .…

Continue reading — create a free account

Join HashtagPLUS to read full articles, follow hashtags, vote, and join the conversation.