Finding a slow production endpoint step by step, with an assertNumQueries test

Backend Live Coding November 13, 2026 python

Measure first: APM (Sentry Performance, New Relic, Datadog) to see where the time goes: database, external APIs, Python.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ======================================================================
# Q: An endpoint is slow in production. Describe step by step how you find the
# cause.
#
# - Measure first: APM (Sentry Performance, New Relic, Datadog) to see where the
#   time goes: database, external APIs, Python.
# - Locally with similar data: django-debug-toolbar or django-silk for the
#   number and duration of queries, and duplicate queries (N+1).
# - For the slow query: qs.explain(analyze=True, buffers=True) and
#   pg_stat_statements. I look for a Seq Scan on a large table, wrong row
#   estimates, a Sort on disk.
# - If the time is in Python: cProfile / py-spy (py-spy also works on a running
#   process, with no code change).
# - Fix it (index, select_related, cache, move to Celery) and add a test with
#   assertNumQueries so the problem does not come back.
# ======================================================================

def test_screen_list_queries(api_client, ws_user, django_assert_max_num_queries):
    ScreenFactory.create_batch(30, workspace=ws_user.workspace)
    api_client.force_authenticate(ws_user)
    with django_assert_max_num_queries(5):     # constant, independent of the count
        r = api_client.get('/api/v2/screens/')
    assert r.status_code == 200