

This prevents a whole class of potential bugs, but it doesn’t completely free the programmer from reasoning about the mechanics of allocation. Go manages memory allocation automatically. Use data to drive your optimization! Analyzing Our Escape These are the same tools that we use at Segment to find bottlenecks in our production Go code, and should be the first thing you reach for as well. It has a solid walkthrough of using pprof for both CPU and allocation profiling. There’s no reason to reinvent the wheel, so instead of taking readers through it here, we’ll refer to this excellent post on the official Go blog.
#Stack vs heap persistent code
Go provides excellent profiling tools that can point directly to the allocation-heavy portions of a code base. Our first recommendation is to avoid premature optimization. We’ll focus on the key mechanics of the allocator that provide developers a way to get a handle on their memory usage.

In this post we’ll cover common patterns that lead to inefficiency and production surprises related to memory allocation as well as practical ways of blunting or eliminating these issues. Tidy, efficient, and precise use of memory is a major part of achieving this consistency. Consistent, predictable behavior is a requirement. Centrifuge is a critical part of Segment’s infrastructure. We found inspiration to share our learnings in this area while building a high-throughput service in Go called Centrifuge, which processes hundreds of thousands of events per second.
#Stack vs heap persistent software
The hot paths of our software must be built in a way that these systems can work efficiently. Automated memory management in Golang helpfully rules out a large class of errors, but that’s only half the story. However, if you’ve ever tried to tune the garbage collector of a JVM program or optimized the allocation pattern of a Go codebase, you understand that this is far from a solved problem. However, after reading the literature, one might be led to believe that all the problems are solved: sophisticated automated systems that manage the lifecycle of memory allocation free us from these burdens. Memory management in Golang can be tricky, to say the least.
