Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For Go 1.25 and later, start with the runtime’s default unless you have measured a reason to pin a different value. The default accounts for logical CPUs, process CPU affinity and, on Linux, cgroup CPU limits; it can also update as those inputs change. Setting GOMAXPROCS manually disables that automatic behavior until you restore it with runtime.SetDefaultGOMAXPROCS.

What GOMAXPROCS controls

GOMAXPROCS sets the maximum number of CPUs that can execute Go code simultaneously. It governs how much parallel execution the Go runtime can use for goroutines; it is not a limit on how many goroutines your program may create. The Go runtime documentation describes it as the maximum number of CPUs executing simultaneously: Go runtime package documentation.

Choose how to configure it

Approach When to use it Effect on automatic behavior
Use the Go 1.25+ runtime default Best starting point when the runtime can see the process’s CPU availability and, on Linux, its cgroup quota. Adapts to relevant changes in CPU availability or quota.
Set the GOMAXPROCS environment variable Use when deployment operators intentionally want a fixed positive integer. Disables automatic default selection and updates.
Call runtime.GOMAXPROCS(n) Use when application code needs to set a fixed value at runtime. Disables automatic updates; returns the previous value.
Call runtime.SetDefaultGOMAXPROCS() Use in Go 1.25+ to restore default selection after a manual override or force an update. Restores the default behavior and ignores the environment variable.
Use GODEBUG compatibility settings Use only when deliberately retaining earlier behavior and after checking language-version and runtime behavior. Can disable cgroup-limit consideration or periodic updates.

Use the Go 1.25+ default

On Go 1.25 and later, the runtime selects its default using logical CPU count and the process CPU-affinity mask, and on Linux it also considers the cgroup CPU throughput limit when one is available. It periodically refreshes the default when relevant availability or quota changes, up to once per second and less often when idle. Go 1.25 introduced container-aware defaults and periodic updating; see the Go 1.25 release notes and the Go Blog explanation.

For a typical containerized service running Go 1.25+, relying on this default avoids having to keep a manually selected value aligned with changing CPU limits. It is a starting point, not a guarantee that every workload will have ideal latency or throughput.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set a fixed value with the environment

Set GOMAXPROCS to a positive whole number in the process environment to request a fixed maximum. For example, a deployment configuration could provide GOMAXPROCS=4. Make sure the value reflects the CPU resources the process can actually use, rather than copying a Kubernetes CPU request: Go’s container-aware behavior considers CPU limits, not requests.

Once the environment variable supplies a manual value, Go does not apply its container-aware default or its periodic updates. That can be intentional when operators want fixed behavior, but it means changes to affinity or cgroup quota will not automatically change the setting.

Set or restore the value in Go code

Set a fixed value

Call runtime.GOMAXPROCS(n) with a positive integer to set the maximum number of CPUs executing simultaneously. The function returns the previous setting. If n is less than 1, it leaves the current setting unchanged. A call with a custom value disables automatic updates. See the runtime package documentation.

Return to runtime defaults

In Go 1.25 and later, call runtime.SetDefaultGOMAXPROCS() to select the runtime default again, ignoring any GOMAXPROCS environment setting. This can restore default selection and updating after a manual override, or force an immediate refresh when the application knows CPU availability, affinity, or cgroup quota has changed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the default means in containers

On Linux, Go derives the cgroup’s average CPU throughput limit from quota divided by period. In cgroup v2 those values are represented by cpu.max; in cgroup v1 they use cpu.cfs_quota_us and cpu.cfs_period_us. In container environments, this generally corresponds to the configured CPU limit, not the CPU request.

The current documented implementation generally uses the minimum of logical CPU count, CPU-affinity count, and cgroup throughput limit. Because GOMAXPROCS is an integer, a fractional throughput limit is rounded up. The implementation generally keeps the value at two or higher, except when the logical CPU count or affinity count is below two. These are implementation details, not permanent API guarantees.

Before Go 1.25, a process in a container could base its default on the host’s logical CPUs even when the container’s lower CPU limit led to kernel throttling. The Go 1.25 container-aware default aims to reduce excess runnable parallelism that can trigger throttling and hurt tail latency. The Go Blog also notes a trade-off: workloads with short, sharp CPU bursts may see latency rise if they can no longer use CPU beyond their average limit. CPU limits can help make latency more predictable, while not imposing them can let workloads use otherwise idle machine capacity; the right choice depends on deployment goals.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep earlier behavior with GODEBUG

Go 1.25 provides two compatibility settings: GODEBUG=containermaxprocs=0 disables consideration of cgroup CPU limits, and GODEBUG=updatemaxprocs=0 disables periodic updates. These settings default to zero for language version 1.24 and earlier. Check both the module’s Go language version and the runtime/toolchain actually used before relying on them. The official GODEBUG compatibility documentation explains how these settings interact with Go versions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to decide whether to override

  • Prefer the Go 1.25+ default when you want the runtime to track CPU availability and, on Linux, visible cgroup quotas.
  • Use a fixed value only when you have a deliberate operational reason and can keep it aligned with the process’s actual CPU availability.
  • Do not base the value on a CPU request alone. The container-aware runtime behavior uses CPU limits, not requests.
  • Consider the workload trade-off. A quota and corresponding parallelism can support predictable latency, while unbounded access may allow opportunistic use of idle CPU.
  • Measure your own workload before choosing a non-default value; official runtime behavior does not establish one universally optimal setting.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.