fastapi-cache-di
Speed up FastAPI startup by caching its dependency-tree introspection.
At startup, FastAPI re-introspects every route's dependency tree with no caching,
so dependencies shared across many routes (auth checks, DB handles, role guards …)
are parsed from scratch again and again. fastapi-cache-di memoizes that work for
the duration of route loading, turning O(routes × tree-depth) into
O(routes + unique-deps), then restores FastAPI's originals.
Install
pip install fastapi-cache-di
# or
uv add fastapi-cache-di
Usage
Wrap the code that loads your routes with the context manager:
from fastapi import APIRouter, FastAPI
from fastapi_cache_di import fastapi_deps_cache
app = FastAPI()
users = APIRouter()
orders = APIRouter()
billing = APIRouter()
with fastapi_deps_cache():
# Registering routes introspects each dependency tree; caching is active here.
app.include_router(users)
app.include_router(orders)
app.include_router(billing)
# originals restored here; cache memory freed
Manual patch/unpatch, sharing and inspecting the cache, and the cache-key details are covered in the documentation.
Calling loop-safe dependencies inline
At request time, FastAPI calls every dependency that is neither a coroutine
nor a generator through the threadpool: every Depends(SomeClass) and every
plain def dependency costs a round trip to a worker thread, often far more
than a class whose __init__ only stores its arguments.
patch_fastapi_run_in_threadpool() lets such dependencies run directly on the
event loop. It is opt-in, because the library cannot tell whether a call blocks:
loop_safemarks one sync function or class (it returns the same object, soDepends(...)anddependency_overrideskeep working);inline_classes=Truetreats every class as loop-safe;- everything else still goes through the threadpool, as do sync generator dependencies and sync endpoints.
from typing import Annotated
from fastapi import Depends, FastAPI
from fastapi_cache_di import loop_safe, patch_fastapi_run_in_threadpool
patch_fastapi_run_in_threadpool(inline_classes=True)
@loop_safe
def get_tenant_id() -> str:
return "acme"
class UserRepository:
def __init__(self, tenant_id: Annotated[str, Depends(get_tenant_id)]) -> None:
self.tenant_id = tenant_id
app = FastAPI()
@app.get("/users")
async def list_users(repo: Annotated[UserRepository, Depends()]) -> str:
return repo.tenant_id
A loop-safe callable must never block: no I/O, no lock, no heavy computation. A blocking call on the event loop stalls every in-flight request. See the documentation for overrides and the marker shared with fastapi-standalone-di.
Skipping the sub-tree of cached dependencies
At request time, FastAPI solves the whole sub-tree of a dependency before
checking whether its value is already in the request's cache, so a dependency
shared across a deep tree is solved again at every occurrence.
patch_fastapi_solve_dependencies() stops that walk as soon as the value is
cached. It is opt-in and stays active for the app's lifetime:
from fastapi import FastAPI
from fastapi_cache_di import patch_fastapi_solve_dependencies
patch_fastapi_solve_dependencies()
app = FastAPI()
The values injected into endpoints are unchanged; see the documentation for the details.
Documentation
Full documentation is available at toilal.github.io/fastapi-cache-di (usage guide, internals, and API reference).
Requirements
- Python ≥ 3.12
- FastAPI ≥ 0.112.4
License
MIT © Rémi Alvergnat
CHANGELOG
v0.3.0 (2026-10-16)
Bug Fixes
-
Patch get_flat_dependant only where FastAPI still defines it (#14,
30fbb28) -
Support FastAPI 0.141+ where get_flat_dependant no longer exists (#14,
30fbb28)
Features
-
Call loop-safe dependencies on the event loop instead of a threadpool hop (#16,
a37d214) -
Skip cached sub-trees when dependency_overrides is set too (#15,
bb8a2f7) -
Skip re-walking the sub-tree of already-cached dependencies at request time (#15,
bb8a2f7)
v0.2.1 (2026-07-06)
Bug Fixes
v0.2.0 (2026-07-05)
Features
v0.1.0 (2026-07-05)
- Initial Release
Changelog entries are generated automatically by python-semantic-release from Conventional Commits on release.
Metadata
Release files for fastapi-cache-di 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_cache_di-0.3.0.tar.gz | 134.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_cache_di-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 151.0 kB
Release files / fastapi_cache_di-0.3.0.tar.gz
| Download URL | fastapi_cache_di-0.3.0.tar.gz |
|---|---|
| Size | 134.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
df22b3727e99a1d517b33243c8b4cf3c16be263542f7706a9f20ef55b86e6fb6
|
|
BLAKE2b-256 checksum How to use checksums |
52d90108286cfe7f15f595e36143b970d08632f8ca8bfea90e83bed6ac5ffe26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / fastapi_cache_di-0.3.0-py3-none-any.whl
| Download URL | fastapi_cache_di-0.3.0-py3-none-any.whl |
|---|---|
| Size | 16.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18723ecbb899acd5c1e33775a265942cac30bd0a64d05d7b15713b3692837714
|
|
BLAKE2b-256 checksum How to use checksums |
d3c4ed34b3d987d5e71be870d61c060b61d11bfe9ace216f1ef7c2cf3c639056
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|