Redis Caching With FastAPI (Optional)
Introduction
Redis stores short-lived data in memory—cached API responses, rate-limit counters, OTP codes. This chapter connects redis-py to FastAPI via lifespan, caches expensive reads, and points to the dedicated Redis track. Skip until you need shared cache across workers.
Prerequisites
- Settings and Configuration
- APIRouter and Project Structure—lifespan hooks
- Redis running locally or Docker:
docker run -d -p 6379:6379 redis:7 pip install redis
Settings
app/core/config.py:
class Settings(BaseSettings):
...
redis_url: str = "redis://localhost:6379/0".env:
REDIS_URL=redis://localhost:6379/0Lifespan Redis Client
app/main.py:
Import get_settings from app.core.config.
Or sync client in lifespan—fine for moderate traffic:
settings = get_settings()
client = redis.Redis.from_url(settings.redis_url, decode_responses=True)
app.state.redis = clientCode explanation:
app.state.redisshared across requests- Close connection on shutdown
Compare Spring Boot Redis and Flask caching.
Cache-Aside Pattern
Code explanation:
setexsets TTL 300 seconds- Invalidate on update:
r.delete(f"item:{item_id}")
Rate Limiting Counter
Use slowapi for richer limits—concept in security chapter.
Dependency Wrapper
def get_redis(request: Request):
return request.app.state.redis
@router.get("/ping-redis")
def ping_redis(r=Depends(get_redis)):
return {"pong": r.ping()}Async Redis (Optional)
pip install redis[hiredis]import redis.asyncio as aioredis
@asynccontextmanager
async def lifespan(app: FastAPI):
client = aioredis.from_url(settings.redis_url, decode_responses=True)
app.state.redis = client
yield
await client.aclose()Use await r.get in async def routes.
FAQ
Cache stale after DB update?
Delete keys on write or use short TTL.
Redis down?
Decide fail-open (skip cache) vs fail-closed (503)—document behavior.
Multiple Uvicorn workers?
Redis shares cache—unlike in-process lru_cache.
Session in Redis?
Possible with session middleware—JWT stateless is simpler for APIs.
Learn Redis deeply?
Continue Redis track.
MongoDB as primary database?
Use PyMongo or Motor in lifespan—not JDBC. See PyMongo with FastAPI and Mongo + Redis project.
Skip chapter?
Yes until traffic or rate limits require shared memory store.