# A Go Concurrency Checklist — Go Concurrency Patterns

Source: https://www.geekswithgeeks.com/en/go-concurrency/gc-checklist

> Review questions before shipping concurrent code.

## Questions to ask in review

For every `go` statement: how does it stop, and who waits for it? For every channel: who owns and closes it, is the buffer size justified, and can every send and receive observe cancellation? Are functions that block taking `ctx context.Context` as the first parameter, and is every `cancel` called? Is shared state guarded by one clearly documented mechanism (a mutex next to the fields, or a single owning goroutine), and are mutexes never copied? Is concurrency bounded with a pool, semaphore or `SetLimit`, and are external calls rate-limited? Are errors collected (errgroup) rather than dropped? Does the service shut down gracefully within a deadline? Do tests run with `-race`, check for leaks and avoid sleeps?

## The checklist

Use it in code reviews.

```text
[ ] every goroutine has an exit path and an owner that waits for it
[ ] no time.Sleep used for synchronisation
[ ] only the sender closes a channel; directional types in APIs
[ ] buffer sizes are justified (default: unbuffered or 1)
[ ] every blocking send/receive also selects on ctx.Done()
[ ] ctx is the first parameter, never stored in structs; cancel() always called
[ ] timers/tickers stopped; no time.After for loop-wide timeouts
[ ] shared state guarded by a mutex next to its fields, or owned by one goroutine
[ ] mutexes and WaitGroups passed by pointer, never copied (go vet)
[ ] concurrency bounded (worker pool, semaphore, errgroup.SetLimit)
[ ] external calls rate-limited (x/time/rate)
[ ] errors collected with errgroup; partial results handled
[ ] graceful shutdown: signal.NotifyContext + Server.Shutdown with a deadline
[ ] go test -race ./... in CI; goleak in tests; goroutine count monitored
```

## Prefer boring concurrency

The best concurrent code looks simple: a few well-named goroutines, clear ownership and standard building blocks such as errgroup and context. If a design needs a diagram to explain who closes which channel, simplify it.

**Quiz:** Which item belongs on a Go concurrency review checklist?

- [ ] Store the request context in the service struct
- [ ] Use large channel buffers to avoid deadlocks
- [x] Every goroutine has a defined way to stop and someone waiting for it
- [ ] Use time.Sleep in tests to let goroutines finish

*Answer:* Every goroutine has a defined way to stop and someone waiting for it. Clear goroutine lifetimes prevent leaks, races at exit and lost work.
