Skip to content
Preptima
mediumConceptScenarioMidSeniorStaff

You put @functools.lru_cache on a method to speed it up, and the service's memory keeps growing. Why, and which fix do you choose?

The cache lives on the class-level function and its keys include self, so every instance the method touches stays strongly referenced and is never collected; with maxsize=None or functools.cache that memory leak is unbounded. Cache per instance with cached_property or an instance dict, or cache plain values.

4 min readUpdated 2026-10-09Target archetype: Product Startup

Answer

Short answer

lru_cache on a method keeps every instance alive. The cache belongs to the function object on the class, and because self is the first argument, each cache key holds a strong reference to an instance. Those instances can never be garbage collected while their entries stay in the cache, and with maxsize=None or functools.cache the memory leak has no ceiling. Cache per instance instead.

Was this answer helpful?

Likely follow-ups

  • Why does cached_property fail on a class that declares __slots__, and what can you add to make it work?
  • How would you cache a method that takes arguments without retaining the instance?
  • What happens to a WeakKeyDictionary entry whose value holds a reference back to its key?
  • Two threads call a cached_property for the first time at once on Python 3.12. What can happen that could not on 3.11?

Related questions

Further reading

Related Topics