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

app/core/config.py:

python
class Settings(BaseSettings):
    ...
    redis_url: str = "redis://localhost:6379/0"

.env:

env
REDIS_URL=redis://localhost:6379/0

Lifespan Redis Client

app/main.py:

Import get_settings from app.core.config.

Or sync client in lifespan—fine for moderate traffic:

python
settings = get_settings()
client = redis.Redis.from_url(settings.redis_url, decode_responses=True)
app.state.redis = client

Code explanation:

  • app.state.redis shared across requests
  • Close connection on shutdown

Compare Spring Boot Redis and Flask caching.

Cache-Aside Pattern

Code explanation:

  • setex sets 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

python
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)

bash
pip install redis[hiredis]
python
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.