Skip to main content

🗄️ purecache

Async-native in-memory cache with pluggable eviction backends — pure Python 3.12+, zero dependencies.

Just asyncio, collections.OrderedDict, and the irrational urge to understand what happens inside the black box.

Part of the pure-python-system-design project.


📦 Installation

pip install purecache

Or with uv:

uv add purecache

Python 3.12+ required.


⚡ Quick Start

Direct backend usage

from purecache.backends.lru import LRUCache

cache = LRUCache(capacity=128)

await cache.put("user:42", {"name": "Alice"})
value = await cache.get("user:42")  # {"name": "Alice"}
value = await cache.get("missing")  # None

Decorator

from purecache.decorators import cache
from purecache.backends.lru import LRUCache

@cache(backend=LRUCache, capacity=128)
async def get_user(user_id: str) -> dict:
    return await fetch_from_db(user_id)

# First call — executes get_user, caches result
user = await get_user("42")

# Second call — returns cached result, skips get_user
user = await get_user("42")

Cache keys are derived automatically from the function's arguments using pickle + SHA-256 — positional args keep their order, keyword args are sorted by name.


🧠 Backends

Backend Eviction Policy Time Memory Best For
LRUCache Least Recently Used O(1) O(n) General purpose
LFUCache Least Frequently Used O(1) O(n) Skewed access patterns
TTLCache Time-based expiry O(1) O(n) Sessions, tokens
LRUTTLCache LRU + TTL combined O(1) O(n) Production default

All backends implement the ICacheBackend protocol — swap them without touching your application code.


🔌 Framework Examples

The decorator integrates naturally with any async framework:

# FastAPI
from fastapi import FastAPI
from purecache.decorators import cache
from purecache.backends.lru import LRUCache

app = FastAPI()

@app.get("/user/{user_id}")
@cache(backend=LRUCache, capacity=512)
async def get_user(user_id: str):
    return await fetch_user_from_db(user_id)

TODO: Add more examples for aiohttp, Django, Flask, Litestar, and Sanic in examples/.


📐 Architecture

cache() decorator
  └── ICacheBackend (protocol)
        ├── LRUCache    — OrderedDict + move_to_end
        ├── LFUCache    — key_map + freq_map + min_freq pointer
        ├── TTLCache    — dict + expiry timestamps
        └── LRUTTLCache — LRU + TTL combined

The cache() decorator handles key generation and cache lookup. The backend handles storage and eviction. Swap the backend, keep everything else.


⚠️ Known Limitations

  • Caching None: The decorator uses if cached_res is not None as the cache-hit check. Functions that legitimately return None will always miss — the value won't be cached. Use a sentinel-aware backend or wrap the return value if needed.

📋 Requirements

  • Python 3.12+
  • Courage

🧪 Development

uv sync
pre-commit install

uv run pytest
uv run ruff check .
uv run mypy src/
uv run mkdocs serve

📖 Documentation

Full docs at https://pure-python-system-design.github.io/purecache/


More designs to come, if the pizza supply holds.

Metadata

Release files for purecache 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for purecache 0.1.0
File Size Uploaded
purecache-0.1.0.tar.gz 8.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for purecache 0.1.0
File Interpreter ABI Platform
purecache-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.3 kB

Release files / purecache-0.1.0.tar.gz

Download URL purecache-0.1.0.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7a37e7e337d8cadc5f90e63467bd395fa182d3237e18807221b02adc9a826080
BLAKE2b-256 checksum
How to use checksums
03f9c5fb5db2dd4ed813af7eb7a0b639450aa49cdc9cc7092001c32a689816df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 4, 2026.

Transparency log

Release files / purecache-0.1.0-py3-none-any.whl

Download URL purecache-0.1.0-py3-none-any.whl
Size 5.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6cf0a774f1d03e916ed2afceac52d98de9707d0197286764da305275dca55c87
BLAKE2b-256 checksum
How to use checksums
ebce91e0774e1ebb20ecb247cda0fbeec4e36e34f2e04416ec684fb2518931de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page