Go Performance Optimization
Optimize an observed constraint, not code that merely looks slow. Preserve correctness, maintainability, and operational safety while improving the metric the user actually cares about.
Establish the Performance Contract
Before editing, record:
- the workload and environment;
- the primary metric, such as latency, throughput, CPU, allocation rate, resident memory, or startup time;
- a representative baseline and its variance;
- the target or regression threshold;
- correctness and resource guardrails;
- whether the bottleneck is inside this Go process or in an external dependency.
If there is no useful evidence yet, gather a focused profile, trace, benchmark, or production metric first. Do not claim an optimization based only on a code pattern.
Diagnose the Dominant Cost
Use the evidence to route the investigation:
| Signal |
Read |
| CPU profile dominated by application code |
references/cpu.md |
| Allocation or retained-heap profile is high |
references/memory.md |
| Time is spent waiting on network, disk, database, or syscalls |
references/io-networking.md |
| GC, scheduler, memory limit, or build profile is implicated |
references/runtime.md |
| Repeated work, hot lookups, or duplicate concurrent requests dominate |
references/caching.md |
| A production change needs metric validation |
references/observability.md |
Load only the references relevant to the measured bottleneck.
Optimization Loop
- Form one specific hypothesis tied to the evidence.
- Define the smallest change and the measurement that can confirm or reject it.
- Keep the benchmark workload, machine constraints, build flags, inputs, and profiling settings comparable.
- Apply one coherent optimization.
- Run correctness checks before trusting performance results.
- Re-measure enough samples to distinguish a change from noise.
- Keep the change only if the target metric improves without violating guardrails.
When several alternatives are plausible, implementation can be explored independently, but measure them serially under comparable conditions. Concurrent benchmark runs compete for resources and invalidate comparisons.
Guardrails
- Prefer algorithmic work avoidance over low-level tuning when both address the same cost.
- Do not trade bounded behavior for unbounded caches, queues, goroutines, buffers, or retries.
- Do not introduce
unsafe, assembly, CGO, pooling, custom allocators, or runtime knobs without profile evidence and focused tests.
- Treat compiler diagnostics as clues, not requirements. Inlining, escape, and bounds-check decisions vary with toolchain and surrounding code.
- Do not replace a standard or existing library with a faster alternative without reviewing correctness, compatibility, maintenance, and security.
- Keep external-service optimization within the user's scope. A slow dependency may require a separate database, network, or capacity investigation rather than Go code changes.
- Document non-obvious performance code with the benchmark/profile scenario and invariant it relies on, not an unqualified speedup claim.
Verification
Run the repository's normal formatting, build, tests, and vet checks. Add checks appropriate to the change:
- race detection for shared state, pools, caches, or concurrency changes;
- integration tests for I/O and protocol behavior;
- benchmark comparisons for hot-path changes;
- heap or goroutine checks for ownership and lifecycle changes;
- production canary metrics when laboratory workloads cannot reproduce the constraint.
Report the exact before/after command or query, environment, central result, uncertainty, and any tradeoff. If the improvement is inconclusive, say so and avoid presenting it as a win.
1---2name: golang-performance3description: Optimize Go code after profiles, benchmarks, traces, or production metrics identify a bottleneck. Use to select and verify CPU, allocation, memory, I/O, caching, concurrency, or runtime improvements against a defined performance target.4license: MIT5---67# Go Performance Optimization89Optimize an observed constraint, not code that merely looks slow. Preserve correctness, maintainability, and operational safety while improving the metric the user actually cares about.1011## Establish the Performance Contract1213Before editing, record:1415- the workload and environment;16- the primary metric, such as latency, throughput, CPU, allocation rate, resident memory, or startup time;17- a representative baseline and its variance;18- the target or regression threshold;19- correctness and resource guardrails;20- whether the bottleneck is inside this Go process or in an external dependency.2122If there is no useful evidence yet, gather a focused profile, trace, benchmark, or production metric first. Do not claim an optimization based only on a code pattern.2324## Diagnose the Dominant Cost2526Use the evidence to route the investigation:2728| Signal | Read |29| --- | --- |30| CPU profile dominated by application code | [references/cpu.md](references/cpu.md) |31| Allocation or retained-heap profile is high | [references/memory.md](references/memory.md) |32| Time is spent waiting on network, disk, database, or syscalls | [references/io-networking.md](references/io-networking.md) |33| GC, scheduler, memory limit, or build profile is implicated | [references/runtime.md](references/runtime.md) |34| Repeated work, hot lookups, or duplicate concurrent requests dominate | [references/caching.md](references/caching.md) |35| A production change needs metric validation | [references/observability.md](references/observability.md) |3637Load only the references relevant to the measured bottleneck.3839## Optimization Loop40411. Form one specific hypothesis tied to the evidence.422. Define the smallest change and the measurement that can confirm or reject it.433. Keep the benchmark workload, machine constraints, build flags, inputs, and profiling settings comparable.444. Apply one coherent optimization.455. Run correctness checks before trusting performance results.466. Re-measure enough samples to distinguish a change from noise.477. Keep the change only if the target metric improves without violating guardrails.4849When several alternatives are plausible, implementation can be explored independently, but measure them serially under comparable conditions. Concurrent benchmark runs compete for resources and invalidate comparisons.5051## Guardrails5253- Prefer algorithmic work avoidance over low-level tuning when both address the same cost.54- Do not trade bounded behavior for unbounded caches, queues, goroutines, buffers, or retries.55- Do not introduce `unsafe`, assembly, CGO, pooling, custom allocators, or runtime knobs without profile evidence and focused tests.56- Treat compiler diagnostics as clues, not requirements. Inlining, escape, and bounds-check decisions vary with toolchain and surrounding code.57- Do not replace a standard or existing library with a faster alternative without reviewing correctness, compatibility, maintenance, and security.58- Keep external-service optimization within the user's scope. A slow dependency may require a separate database, network, or capacity investigation rather than Go code changes.59- Document non-obvious performance code with the benchmark/profile scenario and invariant it relies on, not an unqualified speedup claim.6061## Verification6263Run the repository's normal formatting, build, tests, and vet checks. Add checks appropriate to the change:6465- race detection for shared state, pools, caches, or concurrency changes;66- integration tests for I/O and protocol behavior;67- benchmark comparisons for hot-path changes;68- heap or goroutine checks for ownership and lifecycle changes;69- production canary metrics when laboratory workloads cannot reproduce the constraint.7071Report the exact before/after command or query, environment, central result, uncertainty, and any tradeoff. If the improvement is inconclusive, say so and avoid presenting it as a win.