Django’s Cache Framework provides a unified API for storing and retrieving computed data across multiple backends (in-memory, database, filesystem, Redis, Memcached) with support for per-site, per-view, template fragment, and low-level caching, while performance optimization encompasses query optimization (select_related, prefetch_related), database indexing, and asynchronous task offloading via Celery.
Caching solves the problem of repeated expensive computations (database queries, template rendering, API calls) by storing results for reuse. Django’s cache API (cache.get, cache.set, cache.get_or_set) abstracts the backend, allowing development with local memory cache and production with Redis/Memcached. Performance optimization complements caching by reducing the need for it — efficient queries, proper indexes, and background processing keep response times low even on cache misses.
- Backend configured —
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/1'}} - Cache key generated — Unique string;
make_key('my_key', version=2)includes prefix and version - Set/Get operations —
cache.set(key, value, timeout=300);cache.get(key, default=None) - Per-view caching —
@cache_page(60 * 15)decorator caches entire response - Template fragment —
{% cache 500 sidebar request.user.id %}...{% endcache %} - Low-level API —
cache.add()(only if not exists),cache.incr(),cache.decr(),cache.delete_pattern()(Redis)
- Backends:
LocMemCache(dev, per-process),RedisCache(Django 4.0+, recommended),MemcachedCache,DatabaseCache,FileBasedCache - Key prefix:
KEY_PREFIXprevents collisions in shared Redis;VERSIONfor cache invalidation on schema changes - Timeouts:
timeoutin seconds;None= forever;0= don’t cache - Cache middleware:
UpdateCacheMiddleware+FetchFromCacheMiddlewarefor per-site caching (requiresCommonMiddleware) - Query optimization:
select_related(FK/O2O → JOIN),prefetch_related(M2M/reverse FK → separate query),only/defer(field subset),indexesin Meta
- Built from: Cache Framework API — Core
cache.get/setinterface - Built from: Cache Backends — Pluggable storage implementations
- Built from: Query Optimization — Reduce DB load before caching
- Builds into: Per-View Caching —
@cache_pagedecorator - Builds into: Template Fragment Caching —
{% cache %}tag - Builds into: Low-Level Cache API —
cache.get_or_set,incr,delete_pattern - Builds into: Memcached — Production backends
- Builds into: Celery Background Jobs — Async task processing
- Builds into: Query Optimization Techniques —
select_related,prefetch_related, indexes - Contrasts with: Flask-Caching — Extension, similar API, less integrated
- Contrasts with: FastAPI Custom Caching — No built-in framework, manual implementation
- Related: Cache Middleware — Site-wide caching layer
- Related: Database Indexes — Complementary performance tool
- LocMemCache in production: Per-process, not shared across workers; use Redis/Memcached
- Cache stampede: Multiple workers compute same missing key; use
cache.add()+ lock orget_or_setwith callable - Cache invalidation: Hard problem; versioned keys (
cache.set(f'v{version}:key', val)) or signals on model save - Query optimization order:
select_relatedbeforefilter;prefetch_relatedwithPrefetchobject for filtered prefetch - Celery serialization: Default pickle; use
jsonserializer for security; task args must be JSON-serializable