python-diskcache

Pure-Python disk and file-backed cache that's faster than Memcached and Redis, with a Django-compatible dict-like API.

Library
PyPI
v5.6.3
2,904stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
38/100Needs Attention
Development Activity0
Maintenance0
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality88
Innovation82
Learning Curve65

DiskCache is a pure-Python disk and file-backed cache library built on SQLite and memory-mapped files, offering a dict-like API that’s compatible with Django’s cache framework. Beyond a simple Cache class, it ships FanoutCache for sharding writes across multiple SQLite databases to reduce lock contention, plus persistent Deque and Index container types that mirror Python’s built-in collections.deque and dict but survive process restarts.

The library targets production workloads: it’s thread-safe and process-safe, supports LRU, LFU, and least-recently-stored eviction policies, and includes cross-process recipes for locking, throttling, and stampede-safe memoization. The project enforces a 98% test-coverage floor across a CI matrix spanning Linux, macOS, and Windows on Python 3.8 through 3.11, backed by hours of dedicated stress testing.

What You Get

  • A Cache class backed by SQLite and memory-mapped files with a dict-like get/set/delete API
  • FanoutCache for sharding reads and writes across multiple SQLite databases to cut lock contention
  • DjangoCache backend that drops into Django’s CACHES setting with no extra configuration
  • Persistent Deque and Index types that behave like collections.deque and dict but survive restarts
  • Concurrency recipes: Lock, RLock, BoundedSemaphore, throttle, barrier, and memoize_stampede

Common Use Cases

  • Caching expensive API responses or computed values on a single host without standing up Memcached or Redis
  • Sharing state across multiprocessing workers using process-safe Cache or Index instances
  • Swapping in as a drop-in Django cache backend for file-based caching that actually scales
  • Building cross-process locks, throttles, and stampede-safe memoization for scheduled jobs and web workers
  • Persisting large objects to disk while keeping a simple in-memory-like interface

Under The Hood

Architecture __init__.py re-exports Cache/Disk/JSONDisk/Timeout from core.py (the single-shard SQLite-and-filesystem storage engine), FanoutCache from fanout.py (shards multiple Cache instances by key hash to reduce lock contention), Deque/Index from persistent.py (built directly on Cache, implementing collections.abc.Sequence/MutableMapping), and concurrency recipes (Lock, RLock, BoundedSemaphore, Averager, barrier, memoize_stampede, throttle) from recipes.py, all composed purely on top of the public Cache.transact()/get()/set() API with no access to internals. DjangoCache in djangocache.py wraps FanoutCache to satisfy Django’s BaseCache interface, guarded by a try/except so Django’s absence doesn’t break the package. This is a genuinely layered design: swapping the core storage engine would only touch fanout.py, persistent.py, and djangocache.py, while recipes.py wouldn’t need to change at all since it only depends on the public transactional API.

Tech Stack Pure Python 3, stdlib only — sqlite3 for the storage engine, pickle/json for value serialization with a selectable mode (raw/binary/text/pickle), and threading for locking — with zero required runtime dependencies (install_requires=[]). Dev tooling is extensive: pytest with pytest-cov enforcing a 98% branch-coverage floor via tox, pytest-django, pytest-xdist for parallel runs, mypy for static checking, pylint/flake8/isort/blue for linting and formatting, and doc8/rstcheck/Sphinx for documentation. GitHub Actions runs the full check matrix (bluecheck, doc8, docs, flake8, isortcheck, mypy, pylint, rstcheck) plus tests across Ubuntu, macOS, and Windows on Python 3.8 through 3.11.

Code Quality tests/ has dedicated suites per module (test_core.py, test_deque.py, test_index.py, test_fanout.py, test_djangocache.py, test_recipes.py, test_doctest.py) plus separate stress-test and benchmark scripts excluded from the coverage-gated run. pytest is configured with --doctest-glob="*.rst", so README and tutorial code samples are executed as tests too. The sampled test_core.py uses fixtures, mocks, and explicit error-path assertions against real exception types rather than superficial happy-path checks. Typing is enforced by mypy but expressed through Sphinx-style docstrings rather than PEP 484 annotations, and error handling favors explicit named exceptions (Timeout, EmptyDirWarning, UnknownFileWarning) over silent failure.

API Design The public API mirrors Python’s own dict/deque semantics closely — Cache supports __getitem__/__setitem__/__delitem__/__contains__ alongside get/set/delete with an ENOVAL sentinel to distinguish a truly absent value from None. FanoutCache and DjangoCache preserve the same method surface via a safe-name-restricted __getattr__ delegation, so code can swap between them with no changes. Concurrency primitives are thin decorators/context managers over the same transact() primitive, keeping the mental model to “a transactional dict on disk.” Getting started needs zero configuration (Cache() creates a temp directory and works immediately), and the doctested README/tutorial examples double as executable documentation — though the single ~2,450-line core.py concentrates SQL generation, disk I/O, and locking together, raising the bar for anyone reading past the public API.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search