Go Slice Growth
Go stopped doubling slice capacities in 1.18, and the capacity you get is not the one the growth formula asked for. This shows both: the formula's answer, the allocator's rounding up to a size class, and what it all costs — with every number read out of the Go toolchain rather than from a blog post.
Nothing you enter is transmitted. There is no endpoint behind this page: the Go that computes the progression is compiled to WebAssembly and runs in this tab, so your numbers never leave the browser.
Start from one of these
Go does not double the capacity
It did until Go 1.18. It does not now, and a great many pages still say otherwise.
Below a threshold, append doubles. Above it the growth factor falls toward 1.25, and it falls on a curve rather than a step: each growth adds a quarter of the current capacity plus a fixed amount, so the ratio slides from 2 down toward 1.25 across several growths rather than switching at one. That is why the ratio column in the table above is full of numbers like 1.63 and 1.38 — values that appear in no blog post because nobody expects them.
And the capacity you get is not the capacity it asked for
This is the half almost nobody accounts for. The growth formula produces a number of elements; the runtime multiplies by the element size to get bytes, and then hands that to the allocator — which does not allocate arbitrary sizes. It rounds up to one of a fixed set of size classes. Those spare bytes are not wasted: the slice gets them as capacity.
So a []byte that the formula says should have capacity 1 comes back with capacity 8, because 8 bytes is the smallest class. A 24-byte struct behaves differently from a 32-byte one for the same reason. The table above shows what the formula asked for and what you actually got, in separate columns, because the difference between them is the point.
Where these numbers come from
Not from memory, and not from a table typed in by hand. The doubling threshold and the two coefficients of the 1.25× step are read out of runtime/slice.go in the Go toolchain installed on the build machine; the size classes and their lookup tables come from internal/runtime/gc. That package cannot be imported — it is internal — so the numbers are extracted by a generator and committed, and a test re-derives every one of them from the standard library on every run. A Go upgrade turns the build red rather than leaving this page quietly describing the previous release.
The model is also checked against reality: the test suite grows real slices with the real runtime, in the same process, and requires every capacity to match.
One thing this does not model
A slice the compiler can prove never escapes is not grown by runtime.growslice at all — the compiler generates its own growth against a stack buffer, and the capacities differ. The progression here is the heap one, which is what you get whenever the slice is returned, stored, or passed somewhere that outlives the function. That is the case worth reasoning about, and it is the one this models.
The size classes
The other tools
- Go Time Layout Converter — strftime to Go, and back — Convert a C strftime format string to a Go reference layout and back, directive by directive, with every unmappable directive named rather than guessed.
- Go Method Sets — why *T implements the interface and T does not — Paste a type and an interface and get both method sets computed by go/types, with the compiler's own error and the rule it follows from.
- Go Struct Field Alignment — offsets, padding, and what reordering saves — Paste a struct and get every field's offset, the padding between them, the total size, and a reordered version with the saving — for the architecture you choose.
- Go Goroutine Dump Analyzer — read a SIGQUIT or panic stack dump — Paste a goroutine dump and get it grouped by state and by stack, with wait durations and the stacks held by far more goroutines than they should be.
- GOGC and GOMEMLIMIT Calculator — which one is actually deciding your heap — Compute both documented target-heap rules, see which one binds, and find out when GOGC has stopped having any effect at all.
- Go Benchmark Comparison — is that 4% real? — Paste two go test -bench outputs and get the Mann-Whitney U comparison: median change, p-value, and an honest answer when there is not enough data to tell.