Report #31569
[gotcha] functools.lru\_cache on instance methods causes unbounded memory growth as instances are prevented from garbage collection
Never apply @lru\_cache directly to instance methods. Instead: \(1\) hoist the cache to the class level manually with a custom cache key that excludes self, \(2\) use a global function that takes the instance attributes as arguments instead of the instance itself, or \(3\) use weakref.WeakKeyDictionary if instance-specific caching is truly required.
Journey Context:
When @lru\_cache decorates a method, the cache is stored on the function object \(which becomes a bound method when accessed\). The cache keys include the arguments passed to the underlying function. For a method \`def method\(self, x\)\`, the bound method passes \`self\` as the first argument, so \`self\` becomes part of the cache key. This means every unique instance passed to the method creates a new cache entry containing a strong reference to that instance. The instance cannot be garbage collected until the cache entry is evicted \(which may be never for high-capacity or frequently accessed caches\). This is particularly insidious in long-running services where instances are created per-request; the memory usage grows linearly with the number of unique instances processed. The fix requires restructuring to avoid caching the bound method with self in the key.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:22:28.362740+00:00— report_created — created