Effort: thorough
api.py is 87,283 LoC and serves scidex.ai. The 2026-04-21 PG pool
exhaustion incident showed we have no per-endpoint visibility into
which routes burn DB budget. The sibling
q-obs-pg-slow-query-detector ranks individual SQL statements; this
spec attributes time at the route level, links each route's worst
query back to its FastAPI handler, and proposes concrete indexes.
Goal: cut p95 of the top-20 routes (by request volume × mean ms) by
≥30 % through targeted indexes only — no schema changes.
api_shared/db.py near_get_pool (line 190): a thin wrapper around the pool'sconnection() context manager that captures the callingrequest.scope["route"].path (set by a new_route_label_middleware in api.py adjacent to_trace_id_middleware) and records to a newroute_db_time table:route_label TEXT, query_hash TEXT, exec_ms FLOAT,
rows INT, ts TIMESTAMP DEFAULT NOW().migrations/<date>_route_db_time.sql —DELETE WHERE ts < NOW()
- INTERVAL '90 days' cron.
scripts/hot_path_optimizer.py:sum(exec_ms) over last 7 days; forpg_stat_statements (already present afterq-obs-pg-slow-query-detector) to pick the dominantquery_hash; runs EXPLAIN (FORMAT JSON, BUFFERS); flagsSeq Scan on tables >100K rows whose WHERE-column has nodata/perf/hot_path_report_<date>.md.
GET /senate/hot-paths lists top-20 routes,CREATE INDEX CONCURRENTLY statement and the EXPLAINscripts/ci/check_no_seqscan_regression.py runs the reportwrk -t4 -c64 -d30s against /senate/quality-dashboard.
q-obs-pg-slow-query-detector so the two pagesq-obs-pg-slow-query-detector — provides pg_stat_statementsq-obs-trace-id-propagation — supplies request.scope adornment.q-perf-cdn-friendly-views — uses route timing to pick_route_label_var ContextVar and_get_route_label() lazy accessor to read the route label from the middleware._maybe_record_route_time() sampled at 5% that writes to route_db_timePGConnection.execute() to time each query and recordfinally block (never blocks on errors).
_route_label_middleware adjacent to_trace_id_middleware (line ~1454). Extracts request.scope["route"].pathmigrations/20260427_route_db_time.sql: Creates route_db_timescripts/hot_path_optimizer.py: Computes top-20 routes bydata/perf/hot_path_report_<date>.md. First report generated:data/perf/hot_path_report_20260427.md (empty table — instrumentationGET /senate/hot-paths: HTML page showing top-20 routes_get_cached_page caching pattern.
scripts/ci/check_no_seqscan_regression.py: Opt-in checkNote: pg_stat_statements extension is not yet installed on this PG
instance. The query_hash column is present but empty; the EXPLAIN join
in hot_path_optimizer.py uses placeholder samples. Install with:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements; (sibling task
q-obs-pg-slow-query-detector should cover this).