# Go Concurrency Quick Reference

## Profiling Commands

| Profile | Command | Shows |
|---------|---------|-------|
| Block | `go test -blockprofile=b.prof` | Where goroutines wait (channels, mutexes, I/O) |
| Mutex | `go test -mutexprofile=m.prof` | Lock contention time |
| Goroutine | `go tool pprof http://host:port/debug/pprof/goroutine` | Goroutine stack dump |
| Trace | `go test -trace=t.out` | Per-goroutine timeline |
| Race | `go test -race ./...` | Data races (mandatory after changes) |

## Sync Primitives Comparison

| Primitive | Use case | Overhead | Notes |
|-----------|----------|----------|-------|
| `sync.Mutex` | Mutual exclusion | ~20ns uncontended | Fastest for exclusive access |
| `sync.RWMutex` | Read-heavy | ~25ns read, ~30ns write | N concurrent readers |
| `chan struct{}` | Signaling | ~50ns send/recv | Use for coordination, not data |
| `chan T` (buffered) | Producer/consumer | ~50ns | Buffer size = concurrency slack |
| `sync.Once` | Init once | ~1ns after first call | Perfect for lazy init |
| `sync.Pool` | Object reuse | ~50ns get/put | GC may reclaim objects |
| `sync.WaitGroup` | Wait for N goroutines | ~20ns per Add/Done | Simple fork-join |
| `errgroup.Group` | Wait + error + limit | ~50ns | Preferred over raw WaitGroup |
| `atomic.Value` | Lock-free read/write | ~5ns | For values rarely written |

## Atomic vs Mutex Performance

| Operation | Atomic | Mutex | Delta |
|-----------|--------|-------|-------|
| Simple increment | 80.4 ns/op | 110.7 ns/op | Atomic **27% faster** |
| Read flag | ~5 ns | ~20 ns | Atomic **4× faster** |
| CAS (compare-and-swap) | ~10 ns | N/A | Lock-free alternative |

Use atomics for: counters, flags, CAS loops, lock-free stacks/queues.
Use mutexes for: complex state, multi-step critical sections, invariant enforcement.

## Worker Pool vs Unbounded Goroutines

| Approach | Performance | Resource Usage |
|----------|-------------|----------------|
| Unbounded `go func()` | Baseline | Unpredictable, OOM risk |
| Worker pool (errgroup) | **28% faster** | Bounded, predictable |

## Goroutine Leak Checklist

1. Every `go func()` must have a termination path
2. Every channel send must have a receiver (or use `select` with `ctx.Done()`)
3. Every `time.After` in a loop should be replaced with `time.NewTimer` + `Reset`
4. Every HTTP client must have a timeout: `&http.Client{Timeout: 10 * time.Second}`
5. Every context must be cancelled: `ctx, cancel := context.WithCancel(parent); defer cancel()`
