Goroutines are cheap — 4KB stacks, fast scheduling. So 'just spawn one per task' is reasonable up to ~100K concurrent. Past that, even the cheap things have costs, and patterns shift.

Advertisement

Worker pools over unbounded goroutines

Spawning one goroutine per incoming request is fine until incoming rate spikes. Use bounded worker pools to cap concurrency; queue overflow with explicit backpressure (drop, reject, or block).

Channel patterns under load

Buffered channels: smooth out producer/consumer mismatch. Select with default: non-blocking sends (good for shedding load). Closing channels signals 'no more work' to N consumers cleanly.

Advertisement

Memory model gotchas

Goroutine N stack starts at 8KB; grows. 100K goroutines = ~1-10GB stack memory under normal use. Profile pprof goroutine count and stack sizes. Long-lived goroutines that don't exit are memory leaks.

Worker pools at scale. Bounded channels for backpressure. Profile goroutine count + stacks before scaling further.