sync.Pool
Use `sync.Pool` only for temporary reusable objects that may be dropped at any GC cycle.
Canonical guidance
- treat
sync.Poolas an optimization only - assume pooled objects can disappear at any GC cycle
- reset reused objects before handing them back out
Use when
- temporary buffers
- short-lived reusable objects under measurable allocation pressure
- high-throughput paths that profiles say allocate too much
Avoid
- storing long-lived state in the pool
- assuming the pool is a cache with retention guarantees
- introducing pools before measuring allocation costs
Preferred pattern
var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
Anti-pattern
- relying on
sync.Poolto keep expensive objects alive for later correctness-critical reuse
Explanation: This anti-pattern is tempting because the API says “pool”, but the runtime may drop entries whenever it likes.
Why
- pooling helps only when the runtime and workload make reuse likely; it is never a correctness primitive
Related pages
Sources
- sync package - Go Team
- A Guide to the Go Garbage Collector - Michael Knyszek