Concurrency
2026
A goroutine leak is one of the most insidious bugs in Go. Unlike a memory leak in C, nothing crashes. No panic, no OOM killer. Your service just slowly grows in memory and CPU usage over hours or days until it falls over — or someone notices the goroutine count in a dashboard.
When goroutines share memory, you need synchronization. Go’s sync package provides the primitives for it. Prefer channels for ownership transfer; use sync when multiple goroutines must touch the same state.
Channels are Go’s primary mechanism for passing data between goroutines. The mantra is: do not communicate by sharing memory; share memory by communicating.
Goroutines are Go’s unit of concurrency. They are the first thing interviewers ask about when the topic turns to concurrency.
2025
In the Go runtime, the scheduler is the engine that manages how thousands of goroutines are multiplexed onto a limited number of operating system threads. To ensure system responsiveness and prevent “resource hogging,” Go employs a mechanism called preemption.
You have a timer loop that resets after each event. The code looks right. The tests pass consistently. Then, once every few hours in production, a value appears in the channel that was not supposed to be there. It corrupts state in a way that is impossible to reproduce locally, because it requires a race window measured in nanoseconds.
You copy a struct to pass it to a helper function. The mutex inside is now two independent locks protecting the same data. Your race detector says nothing. Your tests pass. Production disagrees — intermittently, and badly.
