The Go App Optimization Series is a collection of technical articles aimed at helping developers write faster, more efficient Go applications. Whether you’re building high-throughput APIs, microservices, or distributed systems, this series offers practical patterns, real-world use cases, and low-level performance insights to guide your optimization efforts.
While Go doesn’t expose as many knobs for performance tuning as languages like C++ or Rust, it still provides plenty of opportunities to make your applications significantly faster. From memory reuse and allocation control to efficient networking and concurrency patterns, Go offers a pragmatic set of tools for writing high-performance code.
We focus on concrete techniques with mesurable impact you can apply immediately—covering everything from core language features to advanced networking strategies.
What’s Covered So Far¶
Common Go Patterns for Performance¶
In this first article, we explore a curated set of high-impact performance pat
11 Comments
parhamn
Noticed the object pooling doc, had me wondering: are there any plans to make packages like `sync` generic?
roundup
Additionally…
– https://go101.org/optimizations/101.html
– https://github.com/uber-go/guide
I wish this content existed as a model context protocol (MCP) tool to connect to my IDE along w/ local LLM.
After 6 months or switching between different language projects, it's challenging to remember all the important things.
nopurpose
Every perf guide recommends to minimize allocations to reduce GC times, but if you look at pprof of a Go app, GC mark phase is what takes time, not GC sweep. GC mark always starts with known live roots (goroutine stacks, globals, etc) and traverse references from there colouring every pointer. To minimize GC time it is best to avoid _long living_ allocations. Short lived allocations, those which GC mark phase will never reach, has almost neglible effect on GC times.
Allocations of any kind have an effect on triggering GC earlier, but in real apps it is almost hopeless to avoid GC, except for very carefully written programs with no dependenciesm, and if GC happens, then reducing GC mark times gives bigger bang for the buck.
ljm
You're not really writing 'Go' anymore when you're optimising it, it's defeating the point of the language as a simple but powerful interface over networked services.
jensneuse
You can often fool yourself by using sync.Pool. pprof looks great because no allocs in benchmarks but memory usage goes through the roof. It's important to measure real world benefits, if any, and not just synthetic benchmarks.
kevmo314
Zero-copy is totally underrated. Like the site alludes to, Go's interfaces make it reasonably accessible to write zero-copy code but it still needs some careful crafting. The payoff is great though, I've often been surprised by how much time is spent allocating and shuffling memory around.
jrockway
GOMEMLIMIT has saved me a number of times. In containerized production, it's nice, because sometimes jobs are ephemeral and don't even do enough allocations to hit the memory limit, so you don't spend any time in GC. But it's saved me the most times in CI where golangci-lint or govulncheck can't complete without running out of memory on a kind-of-large CI machine. Set GOMEMLIMIT and it eventually completes. (I switched to nogo, though, so at least golangci-lint isn't a problem anymore.)
nikolayasdf123
nice article. good to see statements backed up by Benchmarks right there
nikolayasdf123
nicely organised. I feel like this could grow into community driven current state-of-the-art of optimisation tips for Go. just need to allow people edit/comment their input easily (preferably in-place). I see there is github repo, but my bet people would not actively add their input/suggestions/research there, it is hidden too far from the content/website itself
EdwardDiego
Huh, this surprises me about Golang, didn't realise it was so similar to C with struct alignment. https://goperf.dev/01-common-patterns/fields-alignment/#why-…
_345
Anyone know of a resource like this but for Python 3?