Lightweight FastAPI middleware for measuring API response time and downstream operation latency.
Current version: 0.1.4
- ⏱️ Measure total API response time
- 🌐 Measure latency of any downstream operation
- 📊 See application vs downstream latency
- ⚡ Designed for async FastAPI applications
- 🪶 Lightweight and simple
- 🚫 No database required
- 🚫 No response headers
When a FastAPI API is slow, it can be difficult to tell whether the time is being spent inside your application or waiting for a downstream service.
Without instrumentation, you might repeatedly write timing code:
import time
start = time.perf_counter()
response = await client.get("https://example.com")
elapsed = (time.perf_counter() - start) * 1000
print(f"Downstream latency: {elapsed:.2f}ms")fastapi-timer provides a simple way to do this:
async with request.state.timer.track("downstream"):
response = await client.get("https://example.com")The middleware then logs:
GET /example
total: 460.98ms
downstream: 459.97ms
application: 1.01ms
- 🕐 total — complete API response time
- 🌐 downstream — time spent in a tracked downstream operation
- ⚙️ application — remaining application processing time
Using uv:
uv add fastapi-timerUsing pip :
pip install fastapi-timerAdd the middleware to your FastAPI application:
from fastapi import FastAPI, Request
from fastapi_timer import TimingMiddleware
app = FastAPI()
app.add_middleware(TimingMiddleware)Track any downstream async operation:
import httpx
@app.get("/example")
async def example(request: Request):
timer = request.state.timer
async with timer.track("downstream"):
async with httpx.AsyncClient() as client:
response = await client.get("https://example.com")
return response.json()A complete working example using a weather API is available in:
examples/weather.py
The weather API is only an example. fastapi-timer can be used with any downstream async operation, including external APIs, microservices, and other network calls.
Run the example locally:
uv run uvicorn examples.weather:app --reloadThen request weather for a city:
curl "http://127.0.0.1:8000/weather?city=Chennai"Example output:
GET /weather
total: 1998.94ms
geocoding - downstream1: 1236.11ms
weather - downstream2: 738.61ms
application: 24.22ms
Install development dependencies:
uv syncRun tests:
uv run pytestRun tests with console output:
uv run pytest -sBuild the package:
uv build- 🐍 Python 3.12+
- ⚡ FastAPI 0.141.1+