Faro web-vitals (Loki, 7d) show /me TTFB p90 ≈ 47s, p99 pinned at the 50s timeout. Root causes:
A. /me (lib/sql/me.ts) — getPlayerCounterparties self-joins ledger_postings with no time window and resolves the player's account set via repeated IN (SELECT … UNION …) subqueries; getPlayerTrajectory/countPlayerTransactions repeat the same UNION-subquery pattern. Fix: resolve account-id list once in the page (from findAccountsForPlayer), pass an explicit account_id IN (…), and add the 90-day window to counterparties.
B. /transactions (lib/sql/ledger.ts) — listTransactions joins all ledger_postings + GROUP BY to compute posting_count before ORDER BY settlement_time LIMIT 50 → O(whole ledger) per load. Fix: order+limit ledger_txns first (idx_ledger_settle_time), compute posting_count via correlated subquery for the 50 rows; drop the firm_players join in countTransactions when q is null.
C. Pool/guardrail (lib/db.ts) — connectionLimit 10 → a 47s query starves the pool and stalls the whole site. Bump default pool to 100 and add SET SESSION max_execution_time on new connections as a runaway-query backstop.
V9 read-path indexes confirmed applied in prod.