GODEBUG and Runtime Knobs

Updated

September 8, 2026

GODEBUG and Runtime Knobs

Overview

The runtime exposes a surprising amount of behavior through environment variables — especially GODEBUG. These are for diagnosis and carefully controlled experiments, not random production toggles without metrics.

Diagram: Knob layers

flow:
  [Runtime]
       |
       v
  [Observe]

Essential Environment

Variable Role
GOMAXPROCS P count / parallel Go code
GOGC GC percent trigger
GOMEMLIMIT Soft memory limit
GODEBUG Comma-separated runtime debug flags
GOTRACEBACK Panic stack verbosity (single, all, crash, …)
GOFLAGS Default flags for go command
GORACE Race detector options

GODEBUG Hits Worth Knowing

Exact keys evolve — check go doc runtime / release notes. Common families:

GODEBUG=gctrace=1 ./app          # GC line traces
GODEBUG=schedtrace=1000 ./app    # scheduler trace every 1s
GODEBUG=asyncpreemptoff=1 ./app  # debug preemption (special)
GODEBUG=http2debug=1 ./app       # HTTP/2 verbose (net/http)
# init-time print of effective settings sometimes available via:
go env

GOTRACEBACK

GOTRACEBACK=all ./app    # all goroutines on panic
GOTRACEBACK=crash ./app  # extra crash info / abort behavior (platform)

Programmatic Knobs

debug.SetGCPercent(50)
debug.SetMemoryLimit(512 << 20)
debug.WriteHeapDump(fd)
runtime.SetMutexProfileFraction(5)
runtime.SetBlockProfileRate(1000)

Safety Rules

  1. Change one knob at a time.
  2. Compare p95 CPU memory goroutines before/after.
  3. Do not ship schedtrace or http2debug at full verbosity in prod.
  4. Prefer GOMEMLIMIT over folklore GOGC=off.

Experiment

GODEBUG=gctrace=1 go run .
package main

import (
    "fmt"
    "runtime"
    "runtime/debug"
)

func main() {
    debug.SetGCPercent(100)
    var keep [][]byte
    for i := 0; i < 200; i++ {
        keep = append(keep, make([]byte, 256*1024))
    }
    fmt.Println("goroutines", runtime.NumGoroutine(), "kept", len(keep))
    keep = nil
    runtime.GC()
}

What to notice: gctrace lines show GC cycles correlating with allocation bursts.

Try next: Capture schedtrace during a latency incident; look for high latencies in scheduling vs your code.