All notes
Technical·March 2025

Go Concurrency, Actually Explained


Goroutines are cheap — a few KB of stack that grows as needed. Channels are the communication mechanism. The model: don't communicate by sharing memory, share memory by communicating.

Mental model: goroutines are workers, channels are conveyor belts. Multiple workers can put things on or take things off. If nobody's ready to receive, the sender waits (for unbuffered channels).

Deadlock happens when goroutines are waiting on each other in a cycle. The race detector (go test -race) catches data races before they catch you.

What I got wrong first: treating goroutines like threads and reaching for mutexes everywhere. The idiomatic Go way is usually channels. When you do need a mutex, you probably know why.

select lets a goroutine wait on multiple channel operations simultaneously — like a switch statement for channels. Useful for timeouts and cancellation patterns.

context.Context is the standard way to propagate cancellation across goroutine trees. Pass it as the first argument, always. Respect it when it's done.