Recursion limit and stack depth

sys · Advanced · 10 min

Deeply recursive code (tree walkers, parsers) hits RecursionError around 1000 levels by default.

CPython limits how deep Python calls may nest. sys.getrecursionlimit() is 1000 by default; exceeding it raises RecursionError, a subclass of RuntimeError. The limit exists to stop infinite recursion quickly and to protect the C stack, whose overflow would crash the whole process with a segmentation fault instead of a catchable exception.

sys.setrecursionlimit(n) raises it. Since 3.11, Python-to-Python calls no longer consume C stack frames, and since 3.12 the limit counts only Python frames while the C stack is guarded separately, so moderately higher limits (say 10,000 to 100,000) are usually fine for pure-Python recursion. Recursion through C code (for example repr of nested lists, json.dumps, pickle) is protected by its own internal limit.

Still, Python has no tail-call optimisation, and each frame costs memory. Before raising the limit, consider:

  • Rewriting with an explicit stack (a list) and a loop; this handles any depth.
  • Using an iterative library function (os.walk instead of hand-written recursion).
  • Running deep recursion in a thread created after threading.stack_size(...) increases its stack.

Catching RecursionError is legitimate when processing untrusted nested input, for example to reject absurdly deep JSON.

Example

import sys

print(sys.getrecursionlimit())        # 1000

def depth(n):
    return 0 if n == 0 else 1 + depth(n - 1)

try:
    depth(5000)
except RecursionError as e:
    print(type(e).__mro__[1].__name__)  # RuntimeError

def depth_iter(n):            # explicit loop: no limit at all
    total = 0
    while n:
        n, total = n - 1, total + 1
    return total
print(depth_iter(5000))               # 5000

sys.setrecursionlimit(10_000)
print(depth(5000))                    # 5000

Remember

  • Default limit is 1000 frames; exceeding it raises RecursionError
  • Raising the limit is safer since 3.11/3.12 but Python still has no tail calls
  • An explicit stack or loop removes the depth problem entirely

Watch out for

  • Setting the recursion limit to millions to 'fix' an infinite recursion bug.

Check yourself

  1. Why does CPython limit recursion depth at all?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/sys.html#sys.setrecursionlimit