Recursion — Visual Learning

Factorial —
The classic entry point to recursion.

factorial(n) is usually the first recursive function anyone writes, and it's the clearest place to see the two halves of recursion: the dive down to a base case, and the multiplication that happens on the way back up. Watch every call push a frame on LearnBug and every return multiply its way back to the answer.

O(n)Time complexity
O(n)Space (call stack)
PythonLanguage

What is Factorial Recursion?

factorial(n) is defined as n × factorial(n-1), with factorial(1) = 1 as the base case. Each call doesn't compute anything itself — it hands off to a smaller call, and only once that smaller call returns does the current call multiply its own n into the result and return.

Why visualization helps

The multiplication doesn't happen where it's written — it happens on the way back up, after the recursive call returns. That's the single hardest thing to hold in your head reading factorial code cold. LearnBug shows every frame stacking up on the dive, then shows each multiplication actually fire as the stack unwinds.

LearnBug — factorial(5) call stack building and unwinding
🖼 Add a LearnBug screenshot here
Two Halves

Every recursive call has a "going down" and a "coming back up"

Going down — building the stack

Each call to factorial(n) immediately calls factorial(n-1) before doing any multiplication — a new frame pushes on top with every call.

Push

Coming back up — unwinding the stack

Once factorial(1) returns 1, every waiting call resumes exactly where it paused, multiplies its own n, and returns — popping its frame.

Pop

The base case is what makes it stop

factorial(1) = 1 is the only case that returns without recursing — without it, the dive would never end (see Base Case vs Recursive Case).

Termination
Walkthrough

factorial(5) — dive to the base case, multiply on the way back

1

factorial(5) calls factorial(4) — nothing multiplies yet

Every call from 5 down to 2 does the exact same thing: check the base case (no), then immediately call one level smaller. Four frames stack up before anything returns.

5waiting
4waiting
3waiting
2waiting
Call stack: factorial(5) → factorial(4) → factorial(3) → factorial(2)  |  Nothing returned yet
2

factorial(2) calls factorial(1) — the base case, returns 1 immediately

n == 1 is true, so this call returns 1 without recursing further. This is the bottom of the dive — five frames deep.

5
4
3
2
1= 1
factorial(1) returns 1 — base case hit, unwind begins
3

factorial(2) resumes, multiplies 2 × 1 = 2, and returns

This is the "coming back up" half. factorial(2) was paused waiting for factorial(1)'s result — now it finally runs its own multiplication and pops off the stack.

5
4
3
22×1=2
factorial(2) returns 2  |  factorial(3) resumes next
4

The unwind continues: 3×2=6, then 4×6=24, then 5×24=120

Each waiting frame multiplies its own n by the result it just received, then hands that new result up to whichever frame is waiting above it.

3×2=6
4×6=24
5×24=120final

Return: factorial(5) = 120 ✓ five pushes down, five multiplications on the way back up

Python Code

Recursive factorial

PythonO(n) time, O(n) call stack
def factorial(n):
    if n == 1:            # base case — stops the recursion
        return 1
    return n * factorial(n - 1)  # recursive case — n waits for the smaller result

result = factorial(5)
print(result)   # 120

Complexity Notes

TimeO(n)Exactly n calls, each doing one multiplication
SpaceO(n)n call-stack frames exist simultaneously at the deepest point
Python's limit~1000 callsfactorial(2000) would hit RecursionError before it hits the base case
Iterative alternativeO(1) spaceA loop-based version avoids call-stack growth entirely — see Recursion vs Iteration

Frequently asked questions

Where does the multiplication actually happen?

Not where it looks like it happens. return n * factorial(n - 1) pauses at the function call — Python must fully evaluate factorial(n - 1) first, which means diving all the way to the base case, before n * can run. The multiplication for each frame happens during the unwind, in reverse order from how the calls were made.

What happens if I call factorial(0)?

With this implementation, it would recurse forever — 0 == 1 is never true, so it keeps calling factorial(-1), factorial(-2), and so on until Python raises RecursionError. A more robust base case checks n <= 1 instead of n == 1, since 0! = 1 by mathematical convention.

Why does factorial grow so fast?

Each additional call multiplies by a larger number — factorial(10) is already 3,628,800, and factorial(20) overflows a 64-bit integer in most languages (Python handles big integers natively, so it won't overflow, but the number gets huge fast). This is why factorial shows up constantly in combinatorics and probability.

Is recursive factorial ever a bad choice in practice?

For any input Python can compute without hitting the recursion limit, it's fine — factorial is a textbook example precisely because it's simple, not because it's the fastest approach. For very large n, an iterative loop avoids call-stack overhead entirely, which matters more as n grows.

Watch the stack build, then unwind

Paste your own recursive function into LearnBug and see every frame push and pop.

Open Playground →