— notes
Go Maps Iteration Order
On this page
I was working on a minimal word counter. Read from stdin, normalize the input, increment the value for the keys in a map[string]int. The output looked sorted. Alphabetically sorted.
I ran it again. Same order. Added more input. Still sorted.
At that point, my instincts kicked in. Go maps are unordered. I knew that. So why was the output behaving so politely?
The non-negotiable fact
Go maps do not guarantee iteration order. Ever. The language spec is explicit.
What is actually happening inside a Go map
A Go map is a hash table. Iteration walks buckets in a runtime-defined sequence, not key order.
graph LR
subgraph "Hash Function"
H["hash(key)"]
end
K1["a"] --> H
K2["b"] --> H
K3["m"] --> H
K4["1"] --> H
H --> B0["Bucket 0\n1"]
H --> B1["Bucket 1\n2"]
H --> B3["Bucket 3\na"]
H --> B4["Bucket 4\nb"]
H --> B6["Bucket 6\nm"]Why the output looked sorted
Small number of keys, short ASCII strings, no map resizing during insertion. Under these conditions, hash values distribute nicely across buckets, and the bucket layout in memory often correlates with lexical order. By coincidence.
graph TD
S["Small ASCII key set"]
L["Large / diverse key set"]
S --> O1["Appears sorted (coincidence)"]
L --> O2["Visibly unordered (reality)"]A simplified mental model
Input keys: a b m x y z 1 2 9
Buckets in memory order:
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
1 2 9 a b m x y z
Iteration walks buckets left to right:
1 2 9 a b m x y zDigits first. Then letters. Within each group, alphabetical-looking. No sorting happened. Change the input distribution, force collisions, trigger a map resize, and this illusion breaks instantly.
Deterministic-looking behavior does not imply guarantees.