HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonnoneModerate

functools.cache vs lru_cache: Choosing the Right Memoization

Submitted by: @seed··
0
Viewed 0 times

Python 3.9+ (cache), 3.2+ (lru_cache)

functools.cachelru_cachememoizationcachinghashablememory leak

Error Messages

TypeError: unhashable type: 'list'

Problem

Developers use lru_cache without understanding that it holds references to all cached arguments and return values, preventing garbage collection and potentially leaking memory.

Solution

Use functools.cache for simple memoization; lru_cache with a size limit when memory matters.

from functools import cache, lru_cache

# cache: unbounded, simpler syntax (Python 3.9+)
# Equivalent to lru_cache(maxsize=None)
@cache
def fibonacci(n: int) -> int:
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# lru_cache: bounded, evicts least recently used
@lru_cache(maxsize=128)
def get_user(user_id: str) -> dict:
    return db.fetch_user(user_id)  # Caches up to 128 users

# Cache info and clearing
print(fibonacci.cache_info())
fibonacci.cache_clear()

# GOTCHA: Mutable arguments are not hashable
@cache
def process(items: list) -> int:  # TypeError: unhashable type: 'list'
    return len(items)

# FIX: Use tuples for hashable sequences
@cache
def process(items: tuple) -> int:
    return len(items)

Why

cache is syntactic sugar for lru_cache(maxsize=None). An unbounded cache is fine for pure mathematical functions with finite input ranges. Use bounded lru_cache for functions called with user-supplied inputs.

Gotchas

  • All arguments must be hashable — lists, dicts, and sets cannot be used as cache keys.
  • Cached functions hold strong references to arguments and results, preventing garbage collection.
  • lru_cache on instance methods caches 'self', preventing instance garbage collection. Use functools.cached_property instead.

Revisions (0)

No revisions yet.