Session

Hunting Goroutines: Go's Experimental Leak Detector

Somewhere in your program, there are goroutines that will never wake up. They're blocked on channel sends that will never complete, waiting on mutexes that nobody will unlock. They're not dead (the runtime still knows they exist), but they're not alive either.

Go 1.26 introduces an experimental goroutine leak detector that changes this. By leveraging the garbage collector's reachability analysis, it can distinguish "waiting for work" from "stuck forever".


[What attendees will learn]

- Why goroutine leaks are insidious: no crash, gradual accumulation
- Common leak patterns: early returns, orphaned senders, forgotten cleanup
- The insight: ask the GC about channel reachability
- How the detector temporarily "hides" channel references
- The new `_Gleaked` goroutine state in the runtime
- Using `pprof/goroutineleak` in tests and production

[Questions to highlight]
- What are the most common goroutine leak patterns?
- How do I add leak detection to my existing tests?
- How do I distinguish real leaks from false positives?
- Should I check for leaks in every test?
- How does the detector work with test subtests?

[Initial outline]

1. The problem: goroutines that never wake up
2. Why detection is hard: waiting looks the same as stuck
3. The insight: reachability implies wakeability
4. Asking the GC nicely: how to detect unreachable channels
5. The mechanism: hiding references, iterative marking
6. The new state: `_Gleaked` joins `_Grunning` and `_Gwaiting`
7. Using it: `pprof.Lookup("goroutineleak")`
8. Real bugs caught: CockroachDB (18), Kubernetes (14), Moby (11)
9. Integrating leak detection into your test suite

[Target audience]

Go developers who write concurrent code, maintain long-running services, or want to catch goroutine leaks before they hit production. The talk covers both practical usage and the elegant GC trick that makes it possible.

If the Program Committee prefers other levels for this subject:

For a beginner audience, the talk would focus on what goroutine leaks are and how to spot them, rather than implementation details. I'd start with the mental model: a goroutine leak is a goroutine that will never terminate, usually because it's blocked waiting on a channel that will never receive or send. The talk would emphasize practical detection, using runtime.NumGoroutine() in tests, the goleak package for automated detection, and reading goroutine dumps with pprof. Code examples would show common patterns that leak (unbuffered channels with no receiver, forgotten context cancellation, time.After in loops) and their fixes. The goal is that attendees leave able to add leak detection
to their test suites and recognize the three or four most common leak patterns in code review.

For an advanced audience: the talk would dive into why leaks happen at the runtime level and sophisticated detection strategies. We'd examine how the Go scheduler manages blocked goroutines, why a leaked goroutine consumes ~2KB of stack (which grows if it ever runs), and how it pins the memory it references. The talk would cover building custom leak detectors that track goroutine creation sites using runtime.Stack, integrating leak detection into production monitoring (not just tests), and analyzing complex leak scenarios involving multiple blocked goroutines forming a cycle. We'd also explore edge cases: goroutines blocked on finalizers, leaks hidden behind sync.Pool, and the interaction between leaked goroutines and the garbage collector. Code examples would include production instrumentation patterns and debugging real-world leak cascades.

Alex Rios

Principal Engineer @Memed

Curitiba, Brazil

Actions

Please note that Sessionize is not responsible for the accuracy or validity of the data provided by speakers. If you suspect this profile to be fake or spam, please let us know.

Jump to top