Skip to content

FastAPI Dependency Cache Fix

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about FastAPI Dependency Cache Fix. We cover key concepts, practical examples, and best practices.

The Problem

FastAPI dependencies run on every request. For expensive operations like database lookups, API calls, or permission checks, this adds unnecessary latency.

Quick Fix

Wrong — dependency runs on every request

from fastapi import Depends, FastAPI

app = FastAPI()

async def get_current_user(token: str):
    # Database query on every request
    user = await db.query(User).filter(User.token == token).first()
    return user

@app.get("/profile")
async def profile(user=Depends(get_current_user)):
    return user

Output: The database is queried on every single request, even when the user hasn't changed.

Correct — cache with dependency

from fastapi import Depends, FastAPI, HTTPException
from functools import lru_cache

@lru_cache(maxsize=128)
def get_settings():
    return Settings()

@app.get("/config")
async def config(settings: Settings = Depends(get_settings)):
    return settings

Output: Settings loaded once and cached. Subsequent requests use cached value.

Request-scoped cache

from fastapi import Request, Depends

async def get_db(request: Request):
    if not hasattr(request.state, 'db'):
        request.state.db = Database()
    return request.state.db

@app.get("/items")
async def items(db=Depends(get_db)):
    return await db.fetch_all("SELECT * FROM items")

Redis-backed dependency cache

import json
from fastapi import Depends
from redis import asyncio as aioredis

async def get_cached_user(user_id: int):
    redis = await aioredis.from_url("redis://localhost")
    cache_key = f"user:{user_id}"

    cached = await redis.get(cache_key)
    if cached:
        return json.loads(cached)

    user = await fetch_user_from_db(user_id)
    await redis.setex(cache_key, 300, json.dumps(user.dict()))
    return user

Cache with TTL

from functools import lru_cache
from datetime import datetime, timedelta

class TimedCache:
    def __init__(self, seconds: int = 60):
        self.seconds = seconds
        self.cache = {}
        self.timestamps = {}

    def get(self, key: str):
        if key in self.cache:
            if datetime.now() - self.timestamps[key] < timedelta(seconds=self.seconds):
                return self.cache[key]
        return None

    def set(self, key: str, value):
        self.cache[key] = value
        self.timestamps[key] = datetime.now()

cache = TimedCache(seconds=30)

async def get_expensive_data(dep=Depends(some_dep)):
    key = "expensive_data"
    cached = cache.get(key)
    if cached:
        return cached
    data = await compute_expensive()
    cache.set(key, data)
    return data

Prevention

  • Use lru_cache for true singleton dependencies (settings, configs).
  • Use request.state for request-scoped caching.
  • Use Redis for cross-process, cross-server caching.
  • Always set TTL to prevent stale data.

Common Mistakes with dependency cache

  1. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  2. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
  3. Using return to exit a function early instead of wrapping a pure value in the monad

These mistakes appear frequently in real-world FASTAPI code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Does lru_cache work with async dependencies?

Yes. lru_cache works with both sync and async functions. Results are cached based on arguments.

How do I invalidate a cached dependency?

Call cached_function.cache_clear() to clear all entries, or design a cache with explicit invalidation keys.

Can I cache per-user dependencies?

Yes. Include user ID in the cache key: cache_key = f"permissions:{user_id}".

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro