Configuring GOMAXPROCS in Go for CPU-Bound Workloads and Container Environments

The GOMAXPROCS variable defines the maximum number of operating system threads that can execute Go code simultaneously. It effectively limits how many OS threads the Go scheduler can use to run goroutines, influencing both concurrent and parallel execution. When GOMAXPROCS=1, all goroutines multiplex onto a single OS thread, achieving concurrency through time-slicing but no true parallelism. Setting GOMAXPROCS higher allows goroutines to spread across multiple threads, enabling parallel execution on multi-core machines.

Default Setting

Starting from Go 1.5, GOMAXPROCS defaults to the number of logical CPU cores visible to the runtime, obtained via runtime.NumCPU(). Earlier versions defaulted to 1.

Modifying the Runtime Value

You can adjust this limit either through an environment variable or directly in code. The environment variable takes precedence if both are set.

export GOMAXPROCS=4   # Linux/macOS
set GOMAXPROCS=4      # Windows
package main

import (
    "fmt"
    "runtime"
)

func main() {
    before := runtime.GOMAXPROCS(0)
    fmt.Println("Previous GOMAXPROCS:", before)

    runtime.GOMAXPROCS(4)
    after := runtime.GOMAXPROCS(0)
    fmt.Println("Current GOMAXPROCS:", after)
}

Passing a value less than 1 to runtime.GOMAXPROCS simply returns the current setting without chenging it.

Pitfalls Inside Docker Containers

The default GOMAXPROCS behavior can cause performance issues when running inside containers with CPU limits. The Go runtime often reads the host machine's logical core count rather than the container's allocated CPU quota. For instance, a container restricted to 250m CPU (0.25 cores) might still report 4 or more logical cores. With GOMAXPROCS set to a high value, the scheduler creates many OS threads all competing for limited CPU shares, leading to excessive context switching and reduced throughput.

The impact worsens on hosts with many cores. To mitigate this, explicitly set GOMAXPROCS based on the actual container limits or desired parallelism. While the Go team has discussed improving container CPU detection (see related proposals), manually configuring this value remains a best practice in containerized deployments.

Tags: Go Golang GOMAXPROCS Concurrency docker

Posted on Mon, 07 Sep 2026 16:36:29 +0000 by Candrew