Python & FastAPI Backend — modern, scalable APIs

← Home
Backend & API

Python & FastAPI Backend — modern, scalable APIs

FastAPI is the reference Python framework for asynchronous REST APIs. It combines native Python type hints with automatic Pydantic validation, auto-generated OpenAPI documentation and ASGI performance comparable to Node.js — without sacrificing code readability.

FastAPI — the fastest Python framework

FastAPI runs on Uvicorn (ASGI server) with Gunicorn for multi-process in production. A simple endpoint reading from Redis cache responds in under 5ms on standard hardware. Native Dependency Injection allows isolated testing of any layer without complex mocks: authentication, database session, rate limiting — each is an injectable dependency.

OpenAPI 3.1 documentation is automatically generated from type hints — Swagger UI and ReDoc available at `/docs` and `/redoc` in development. Pydantic v2 schema (Rust-based validator) validates requests and responses 10–20x faster than Pydantic v1. Any invalid field returns a 422 with clear, localised error messages.

  • Native async/await — non-blocking I/O on all DB and HTTP operations
  • BackgroundTasks for post-response operations (email, webhook, log)
  • Native WebSocket support for real-time features (chat, notifications)
  • Rate limiting with slowapi (limits-based) — per-IP and per-user
  • CORS, compression (gzip/brotli), request ID, timing middleware

PostgreSQL, SQLAlchemy and Alembic

We use SQLAlchemy 2.0 async (asyncpg driver) for all DB operations. Models are defined with Mapped types — type-safe, no strings. Complex queries are written in SQLAlchemy Core (compile-time checked) or pure SQL via `text()` with bind parameters — never string interpolation (complete SQLi prevention).

Alembic migrations are auto-generated from model changes and manually reviewed before application. Each migration has tested `upgrade()` and `downgrade()`. In production, migrations run in CI before deploy — the database is always in sync with the code. Connection pooling via asyncpg with configurable pool size per service.

  • Row-level locking with `SELECT ... FOR UPDATE` for critical concurrent operations
  • Full-text search with pg_trgm and tsvector — no Elasticsearch for simple cases
  • JSONB for semi-structured data with GIN indexing
  • Partition tables for tables with millions of rows (logs, events)

Redis caching and horizontal scalability

Redis 7 is used for application cache (per-endpoint TTL), session store (JWT refresh tokens with selective revocation), pub/sub for real-time events and queues for background jobs (Celery or ARQ). Caching strategy is cache-aside with explicit invalidation — not blind TTL that may serve stale data.

  • JWT auth with access token (15min) + Redis refresh token (7 days)
  • Celery + Redis broker for async tasks (PDF gen, email, imports)
  • Health check endpoint `/health` with DB, Redis status and deploy version
  • Structured JSON logging (structlog) — compatible with Loki/Datadog/ELK

Pros and cons

Pros

  • ASGI performance comparable to Node.js and Go on I/O.
  • OpenAPI documentation auto-generated from type hints.
  • Fast Pydantic v2 validation, with clear 422 errors.
  • Readable code, Python familiar to most teams.

Limitations

  • Python stays slower than Go or Rust on CPU-intensive tasks.
  • async/await requires discipline — one blocking call stalls the whole event loop.
  • Younger ecosystem than Django for batteries-included features.
  • No built-in ORM or admin — you choose them separately.

Quick verdict

Choose FastAPI for async REST APIs, microservices and backends for SPA/mobile. For extreme CPU-bound apps or monoliths with a ready-made admin, Go or Django respectively can fit better.

Specifications table

CapabilityLimit / thresholdTypical use
Concurrencyasync/await, non-blocking I/OCPU-bound needs separate workersAPIs with many DB/HTTP calls
Latency< 5ms per endpoint with Redis cacheGrows with large payload serializationCheckout, cart, real-time stock
Validation & docsPydantic v2 + OpenAPI 3.1 autoComplex schemas increase startup timePublic APIs with Swagger/ReDoc
Typical costOpen-source, runs on 1 vCPUHorizontal scaling needs more processesFrom MVP to production

FastAPI vs alternatives

CriterionFastAPIDjango / Express
Async performanceExcellent (native ASGI)Django partial, Express good
Automatic OpenAPI docsYes, from type hintsNeeds extra packages
Built-in admin / ORMNo (choose separately)Django: yes; Express: no

Frequently asked questions

Is FastAPI faster than Django?

Yes for I/O. FastAPI runs async on ASGI, so it handles far more concurrent requests with DB/HTTP calls than classic synchronous Django. Django, however, has more built-in features.

What is FastAPI not suited for?

For heavily CPU-bound tasks (image processing, heavy numerical computation) Python is slower than Go or Rust; you move those to separate workers. It also lacks a ready-made admin like Django.

Does FastAPI need an ORM?

Not mandatory. We use SQLAlchemy 2.0 async with Alembic for migrations, but you can write pure SQL. The ORM is not bundled, so you choose it per project.

How do I scale a FastAPI backend?

Horizontally: run multiple Uvicorn processes under Gunicorn behind a load balancer, with Redis cache and heavy tasks moved to Celery. Stateless design lets you add instances on demand.