How deep — and what happens at the end
Wire walk and depth into main.go. algo depth builds a chain — a folder
inside a folder inside a folder, no branching — so the recursion depth equals n.
Guess before you read on
A Go goroutine stack grows by itself: it starts at about 8 kilobytes and expands as needed. A C thread stack is fixed — usually 1–8 megabytes — and when you reach the end, your process dies.
How deep do you think Go's recursion goes? Write the number down before you look.
The answer
$ algo depth -n 1000000
recursive walk of a chain 1000000 deep: 1000000 items, 1000001 folders, 72ms
$ algo depth -n 8000000
recursive walk of a chain 8000000 deep: 8000000 items, 8000001 folders, 621ms
Eight million frames. No trouble at all, in 0.6 seconds.
If you guessed thousands or tens of thousands — that would have been C. Go grows the stack as far as it needs, up to a default ceiling of one gigabyte.
And where it does end
$ algo depth -n 16000000
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
main.WalkRecursive(0x0?, 0x2bd4e9b5fe28)
.../walk.go:28 +0x45 fp=0x2bd4c9b61f98 sp=0x2bd4c9b61f58
main.WalkRecursive(0x0?, 0x2bd4e9b5fe28)
.../walk.go:28 +0x45 fp=0x2bd4c9b61fd8 sp=0x2bd4c9b61f98
...8388426 frames elided...
Three things in that message are worth your attention.
"fatal error", not "panic". You cannot catch this with recover. The
program is over. It is the one Go failure you do not get to handle.
The limit is stated exactly: 1,000,000,000 bytes.
Go tells you how many frames it hid: ...8388426 frames elided.... From that
you can work out the frame size:
1,000,000,000 B ÷ 8,388,426 frames ≈ 119 bytes per frame
Every WalkRecursive call costs about 119 bytes. That is the price of the
"hidden" stack.
The same work, on your stack
$ algo depth -n 16000000 -iterative
iterative walk of a chain 16000000 deep: 16000000 items, 16000001 folders, 129ms
The same depth that killed the recursion. The iterative version walks it in
129 milliseconds without breaking a sweat — because its stack is a
[]*Folder on the ordinary heap, and the heap has no 1 GB ceiling.
And it is faster everywhere, not just at the limit: 72 ms against 8 ms at a million. A function call is not free.
This is exactly why transit writes BFS iteratively. Not because a 1,531-stop
graph is too deep — it is not. But because recursion depth is set by the
input, and a limit you cannot catch is a limit you cannot manage. When the
data decides the depth, the stack has to be yours.