Last Updated: May 22, 2026
Concurrent code fails in ways sequential code never does. A goroutine that should have exited is still hanging around, two goroutines mutate the same counter and produce the wrong total, a service that handled traffic fine yesterday is suddenly leaking memory because its goroutine count keeps climbing. This lesson covers the tools Go ships for finding those bugs: counting goroutines at runtime, dumping stacks on demand, profiling with pprof, catching data races with -race, and getting scheduler visibility through GODEBUG.