SkillByAIOpen interactive version →

Lesson 25 / 26

Performance and Scaling

Measure, cache, offload.

Usual bottlenecks

Most slow Python web apps are slow because of the database: N+1 queries, missing indexes, large result sets. Fix those first, then add caching (Django's cache framework with Redis, HTTP caching headers), move slow work to background jobs (Celery, RQ, Dramatiq, or arq for async), paginate lists, and use connection pooling. Profile with real data and load tests before rewriting anything for speed.

A performance triage order

Work down the list.

1 measure: slow query log, APM traces, Debug Toolbar / query counts
2 database: indexes, select_related/prefetch_related, pagination
3 caching: per-view or per-object caches in Redis; HTTP cache headers
4 background jobs: emails, reports, image processing out of the request
5 concurrency: workers, async for I/O-bound endpoints
6 only then: rewrite hot paths or split services

Fix queries before adding servers

More workers multiply the load of inefficient queries on the database.

Quick check: What is the most common cause of slow Django or FastAPI endpoints?

  • Python syntax
  • The choice of web framework
  • Inefficient database access
  • Too few comments
Answer

Inefficient database access — Measure the database first.