How to Use lru_cache in Python for Cache-on-Miss Population

Demonstrates lru_cache to automatically populate cache on a miss and serve subsequent calls from cache, with cache info stats.

Easy Python 3.9+ Aug 9, 2026 Caching & Redis 15 views 0 copies

Python code

18 lines
Python 3.9+
from functools import lru_cache

@lru_cache(maxsize=None)
def fetch_user(user_id):
    """Simulates a slow database fetch."""
    print(f"Cache miss: fetching user {user_id} from database")
    return {"id": user_id, "name": f"User {user_id}"}

if __name__ == "__main__":
    user = fetch_user(1)
    print(f"First call: {user}")
    
    # Second call hits cache - no database message printed
    user_again = fetch_user(1)
    print(f"Second call: {user_again}")
    
    # Verify cache stats
    print(f"Cache info: {fetch_user.cache_info()}")

Output

stdout
Cache miss: fetching user 1 from database
First call: {'id': 1, 'name': 'User 1'}
Second call: {'id': 1, 'name': 'User 1'}
Cache info: CacheInfo(hits=1, misses=1, maxsize=None, currsize=1)

How it works

The @lru_cache decorator wraps fetch_user and automatically caches return values keyed by arguments. On the first call, a miss triggers the function body (printing the miss message) and stores the result. The second call with the same argument hits the cache and returns instantly without re-running the function. cache_info() reports hits, misses, maxsize, and current size, giving visibility into cache efficiency. This is a simple read-through pattern where the function itself is the data source.

Common mistakes

  • Using `maxsize=None` for unlimited cache may cause memory growth; set a finite size for production.
  • Assuming the function is not executed on cache hits — forget that side effects like print only run on misses.
  • Forgetting that arguments must be hashable; lru_cache fails with unhashable types like lists.
  • Not clearing the cache when underlying data changes, leading to stale values.

Variations

  1. Add a timeout-based refresh by manually clearing the cache with `fetch_user.cache_clear()`.
  2. Use `functools.cache` (Python 3.9+) for a simpler unlimited cache with the same behavior.

Real-world use cases

  • Memoizing expensive database queries in a web service to reduce latency.
  • Caching API responses in a microservice to avoid repeated network calls.
  • Caching configuration or rarely-changing computed values in a data pipeline.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Caching & Redis

Related tutorials and quizzes for this topic.