How does GOMAXPROCS interact with containers, and how does it affect GC?
GOMAXPROCS is the number of Ps, which is the maximum number of threads running Go code at the same time. Before Go 1.25 it defaulted to the host's CPU count and ignored cgroup CPU limits. A pod limited to 2 CPUs on a 64-core node got GOMAXPROCS=64, which caused CFS throttling, latency spikes, and 16 dedicated GC workers (25% of 64) fighting over 2 CPUs of quota. The usual workaround was go.uber.org/automaxprocs.
Go 1.25 and later, when go.mod says go 1.25 or newer:
- On Linux, the default takes the cgroup CPU limit into account, rounded up and with a minimum of 2.
- The runtime re-checks it periodically and adjusts if the limit or the CPU affinity changes.
- Setting
GOMAXPROCSexplicitly, or callingruntime.GOMAXPROCS(n), turns this off.runtime.SetDefaultGOMAXPROCS()turns it back on. The GODEBUG settingscontainermaxprocs=0andupdatemaxprocs=0opt out.
func main() {
fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0)) // 0 = query only
}
Effect on GC: background marking uses 25% of the Ps, so GOMAXPROCS directly scales GC parallelism. It also sets the number of per-P mcaches, sync.Pool shards and timer heaps.
What the interviewer is looking for: you have hit CPU throttling in Kubernetes, and you set GOMEMLIMIT (memory) and GOMAXPROCS (CPU) together from the pod's resource limits.
More on Memory, GC & Runtime Internals
- Q362Is
time.Afterin a loop a memory leak? What changed in Go 1.23? - Q363How do you find a memory leak in production with pprof?
- Q365What are the runtime representations of Go's built-in types? What does this print on 64-bit?
- Q366What is bounds-check elimination and how do you help the compiler do it?
- Q367What is profile-guided optimisation (PGO) in Go and what does it actually change?
- Q368How does the runtime preempt goroutines, and what are GC safe points?