Skip to content

docs: document lru_cache async footgun in comparison guide #77

@27Bslash6

Description

@27Bslash6

Description

functools.lru_cache on async functions is a well-known footgun — it caches the coroutine object, not the awaited result. Second call raises RuntimeError: cannot reuse already awaited coroutine.

This is a genuine cachekit advantage that should be documented in the comparison guide.

Evidence

from functools import lru_cache

@lru_cache(maxsize=128)
async def fn(x):
    return x * 2

result1 = await fn(1)  # Works — returns 2
result2 = await fn(1)  # RuntimeError: cannot reuse already awaited coroutine

cachekit handles this correctly:

@cache(backend=None, ttl=300)
async def fn(x):
    return x * 2

result1 = await fn(1)  # Works — returns 2
result2 = await fn(1)  # Works — returns 2 (from cache)

Suggested Fix

Add an "Async Support" section to docs/comparison.md documenting:

  • lru_cache: caches coroutine, not result (broken)
  • cachetools: no async support
  • aiocache: async-first (works)
  • cachekit: works with both sync and async (auto-detected)

Found by: tests/competitive/test_head_to_head.py::TestAsyncSupport

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions