Go

What is GOMAXPROCS, what is its default, and what changed in Go 1.25 for containers?

Question 155MediumGo 1.22 to 1.25

GOMAXPROCS is the number of Ps, which is the maximum number of threads executing Go code at the same time. Threads blocked in syscalls or cgo do not count toward it. The default has been runtime.NumCPU() since Go 1.5. NumCPU respects the CPU affinity mask.

Before Go 1.25 the runtime ignored cgroup CPU quotas. A pod limited to 2 CPUs on a 64-core node got GOMAXPROCS=64. The result was CFS throttling, latency spikes and extra GC CPU. The usual workaround was go.uber.org/automaxprocs.

Go 1.25 (Linux) made the default container-aware:

  • The default is the minimum of the core count (affinity mask) and the cgroup CPU limit, rounded up, with a floor of 2 (never above the CPU count). CPU requests are ignored.
  • The runtime checks periodically and updates GOMAXPROCS if the limit or the affinity changes.
  • Both behaviours turn off if you set the GOMAXPROCS environment variable or call runtime.GOMAXPROCS(n). runtime.SetDefaultGOMAXPROCS() brings them back.
  • They depend on the go version in go.mod. You can control them with GODEBUG=containermaxprocs=0 and updatemaxprocs=0.
fmt.Println(runtime.GOMAXPROCS(0)) // 0 = query without changing

More on Goroutines & the Scheduler

All 35 Goroutines & the Scheduler questions