Go

Do Go maps shrink after you delete entries? How do you reclaim the memory?

Question 360HardGo 1.22 to 1.25

No. delete and clear(m) free the slots for reuse, but the map's bucket and table storage never shrinks. If a map briefly held 10 million entries, it keeps that memory until the whole map becomes unreachable. This is true for the classic bucket map and for the Swiss-table implementation that became the default in Go 1.24. Swiss tables use less memory per entry and look up faster, but they still do not shrink.

// Reclaim by rebuilding: allocate a right-sized map and copy live entries.
func compact[K comparable, V any](m map[K]V) map[K]V {
    out := make(map[K]V, len(m))
    for k, v := range m {
        out[k] = v
    }
    return out
}

// usage, inside a function; the old map becomes garbage:
//     sessions = compact(sessions)

Gotcha: maps.Clone is not a way to shrink. It may copy the internal structure at its current size. Use a fresh make with a size hint and copy into it.

Related tips:

  • Large values: map[K]*V lets the element memory be freed even though the table stays. Large map[K]V values are stored inline, or indirectly if bigger than 128 bytes.
  • Maps with no pointers in their keys or values, like map[int]int, are not scanned internally by the GC. That makes them much cheaper for large caches than map[string]*T.
  • For long-lived caches with churn, use size limits and eviction, or shard and periodically rebuild.

More on Memory, GC & Runtime Internals

All 38 Memory, GC & Runtime Internals questions