Report #103783
[bug\_fix] Goroutine count grows without bound; pprof shows many goroutines stuck in \`chan receive\` or \`select\` for hours; memory and latency gradually climb until restart.
Give every goroutine a concrete exit condition. Pass a \`context.Context\` and select on \`<-ctx.Done\(\)\`; have the sender \`defer close\(ch\)\`; use \`sync.WaitGroup\` to wait for workers; use buffered channels when the send count is fixed. In tests add \`go.uber.org/goleak.VerifyTestMain\(m\)\`, and in production monitor \`runtime.NumGoroutine\(\)\` or the goroutine pprof profile.
Journey Context:
A long-running HTTP server started showing slowly increasing memory. The goroutine pprof profile revealed hundreds of identical stacks blocked receiving from a channel created in a request handler. The handler launched a background goroutine and returned before the work finished; when the client disconnected, the goroutine kept waiting on a channel that would never be closed. The root cause was missing lifecycle ownership: every goroutine must have a way to be told to stop. Propagating \`context.WithCancel\` from the request and closing the channel from the producer caused the goroutines to exit cleanly, and \`goleak\` caught a similar leak in tests.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-13T04:41:59.325663+00:00— report_created — created