Packages, modules and tooling · 3 MIN READ
A microbenchmark is not a capacity test
Measure allocations, concurrency and tail latency without mistaking closed-loop throughput for service capacity.
An ns/op number describes one workload in one process. A production incident may instead come from pool wait, queue growth, a slow downstream service or allocation pressure. Start with the question you need to answer and preserve the workload and environment alongside the measurement.
Packages and production tooling · A MAP OF THE IDEA
- Question
- Representative workload
- Resource evidence
- Latency distribution
Useful when
- Measure allocations, concurrency and tail latency without mistaking closed-loop throughput for service capacity.
Watch out
- A microbenchmark measures its own loop and inputs. It may omit network, pool wait, queue growth and overload failures that dominate a real service.
Implementation & operation cost: Useful measurements require representative inputs, repeated runs and separate whole-service load evidence.
Repeat a focused microbenchmark
Select one benchmark, include allocation reporting and repeat it. Keep setup outside the timed section where that matches the production operation. Optimizing a string conversion says little about the complete HTTP-to-database request unless the conversion dominates that request.
go test ./internal/codec -run='^$' -bench=BenchmarkEncode -benchmem -count=5
go test ./internal/codec -run='^$' -bench=BenchmarkEncode -cpu=1,2,4Replace the package and benchmark with real ones. Repeated measurements expose noise; CPU variants reveal scaling effects, but they do not reproduce a network load generator or a remote database.
Make parallel measurements honest
RunParallel measures concurrent benchmark work using a closed loop. Retain observable work, avoid sharing an unsafe buffer, and define whether the benchmark measures hits, misses or both. Report failure rate, request sizes and queue limits for a service test instead of only a flattering average.
var benchmarkBytes []byte
func BenchmarkEncode(b *testing.B) {
input := []byte("catalog-item")
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
out := append([]byte(nil), input...)
benchmarkBytes = out
if len(out) != len(input) { b.Fatal("short copy") }
}
}This is a self-contained benchmark body importing testing. It intentionally includes the allocation and validates the result; use a representative payload before comparing implementations or drawing a capacity conclusion.
Look at the tail and overload response
At a steady incoming arrival rate, a saturated service can build a queue even while successful completions look fast. Observe p50/p95/p99 together with errors, active requests, pool checkout time and recovery after a burst. An unbounded queue delays failure instead of creating capacity.
TAKE THIS WITH YOU
Use benchmarks to answer narrow code questions, then test the complete service with an explicit arrival rate, bounded queues and tail-latency/error measurements.
Check your understanding
What can a low ns/op result prove about a database-backed API?
Go to the source
Progress stays in this browser. No account needed.