FastAPI: From Basics to Production · Deployment, Observability and Performance

Performance Tuning

Find and fix the real bottlenecks in FastAPI services.

Most FastAPI slowness comes from blocking calls in async code, N+1 queries, missing indexes, chatty external calls and large payloads. Profile (py-spy, pyinstrument, traces), then: use async drivers end to end, eager-load relationships, add indexes, cache hot reads in Redis, run independent I/O concurrently, paginate, compress responses (GZip), and consider faster JSON (ORJSONResponse) for very large payloads. Load test with Locust or k6 to verify.

from fastapi.middleware.gzip import GZipMiddleware
import asyncio

app.add_middleware(GZipMiddleware, minimum_size=1024)

sem = asyncio.Semaphore(20)


async def fetch_price(http, sku: str) -> int:
    async with sem:                                   # bounded concurrency
        r = await http.get(f"https://pricing/skus/{sku}")
        r.raise_for_status()
        return r.json()["price_cents"]


async def prices(http, skus: list[str]) -> dict[str, int]:
    results = await asyncio.gather(*(fetch_price(http, s) for s in skus))
    return dict(zip(skus, results))
py-spy top --pid $(pgrep -f "uvicorn")      # live CPU profile of a worker

Common pitfalls

  • Optimizing JSON serialization while the database dominates latency.
  • Unbounded concurrency overwhelming downstream services.
  • Load testing with unrealistic data volumes.

Key points

  • Profile first
  • Async end to end; bounded concurrency
  • Fix queries, cache hot reads, paginate

Further reading: FastAPI: Custom responses

Practice questions

Your async endpoint's latency spikes under load while CPU is low. What's a likely cause?

Answer

Blocking calls inside async code (sync DB driver, requests, file I/O) stalling the event loop, or connection pool exhaustion; check with profiling and pool metrics.

Why use a semaphore with asyncio.gather for many outbound calls?

Answer

To cap concurrency so you don't overwhelm the downstream service, exhaust connection pools or trigger rate limits.

Open in the app to mark lessons complete, take notes and track your progress.