Before you put a FastAPI service in front of users, work through this list. Some items are framework-specific; most apply to any Python web service.

Configuration

  • pydantic-settings with env validation at startup.
  • Secrets via secret manager (Vault / AWS SM / GCP SM) — never in code/image.
  • Per-environment config (dev/staging/prod) wired and tested.
  • SECRET_KEY and JWT signing keys rotated procedure documented.

Dependencies

  • uv.lock committed; CI uses uv sync --frozen.
  • Dependabot / Renovate enabled.
  • Security scan in CI (pip-audit, trivy, grype).
  • Pinned base image digest in Dockerfile.

App structure

  • lifespan for engines, pools, HTTP clients.
  • DB session is per-request via Depends.
  • expire_on_commit=False on AsyncSessionLocal.
  • response_model set on every public endpoint.
  • include_in_schema=False for internal health/metrics endpoints.
  • All blocking calls audited (no time.sleep, requests, sync DB in async paths).

Error handling

  • Custom exception handlers for RequestValidationError, app errors.
  • Don’t leak stack traces in production responses.
  • Sentry / equivalent error tracker wired with environment + release tags.

Auth

  • Argon2 (or bcrypt) password hashing.
  • JWT verification pins algorithms=[...] explicitly.
  • Refresh tokens stored hashed; revocable.
  • Rate-limit /token and password-reset endpoints.
  • Generic ‘invalid credentials’ error (no enumeration).
  • CORS allow-list pinned to actual frontends.
  • HTTPS-only cookies (Secure, HttpOnly, SameSite=Lax|Strict).

Database

  • Pool sized for workers × replicas × (pool_size + max_overflow) ≤ db_max_connections (or use PgBouncer).
  • pool_pre_ping=True, pool_recycle=3600.
  • All migrations applied via Alembic (no Base.metadata.create_all in prod).
  • Migration runs as K8s Job before app rollout.
  • Backups + point-in-time recovery configured AND tested.
  • Read replicas used for read-heavy paths if needed.

Performance

  • No N+1: selectinload / joinedload audited.
  • Cursor pagination, not offset, for large datasets.
  • Slow query log + alerts.
  • Background tasks for anything > ~100ms that doesn’t need to block the request.
  • CDN cache headers for cacheable responses.

Observability

  • Structured JSON logs to stdout.
  • Request ID + user/tenant ID in every log line (via contextvars).
  • OTEL tracing wired (FastAPI + httpx + DB).
  • Trace ID in log lines (correlation).
  • Prometheus metrics endpoint exposed.
  • Dashboards: request rate, error rate, p50/p95/p99 latency, DB pool, queue depth.
  • SLOs defined; burn-rate alerts wired.

Security

  • HSTS header.
  • CSP if serving HTML.
  • X-Content-Type-Options: nosniff, X-Frame-Options: DENY.
  • CORS configured deliberately.
  • Input validation strict; no SQL string concatenation.
  • File uploads: size limited; type checked; stored outside web root.
  • Dependencies SBOM generated; signed images (cosign).

Deployment

  • Multi-stage Dockerfile; non-root user; distroless or slim runtime.
  • K8s Deployment with >= 2 replicas.
  • startupProbe, readinessProbe, livenessProbe all wired.
  • terminationGracePeriodSeconds + preStop sleep.
  • HPA configured (CPU or custom metric).
  • PodDisruptionBudget set.
  • Resource requests + memory limits.
  • Deploy strategy chosen (rolling default; canary for risky changes).

Capacity / load

  • Load tested to expected peak × 2.
  • Capacity ceiling per replica known.
  • Cost per request roughly known.

Operational readiness

  • Runbook for top alerts.
  • On-call rotation set up.
  • Pager / Slack alerts tested end-to-end.
  • Rollback procedure tested (Helm rollback, image tag revert).
  • Postmortem template ready.

Documentation

  • OpenAPI spec published.
  • Auth flow documented for integrators.
  • Architecture diagram in repo.
  • CONTRIBUTING.md / dev-setup.md current.

Day-one launch

  • Soft launch behind feature flag for a cohort.
  • Monitor SLOs for 24h.
  • Rollout to 100% once SLOs stable.

Read this next

If you want my full FastAPI production starter (lifespan, observability, auth, migrations, Helm), it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .