From 7f668c9a5f7569901de3ddc9b9a887824f3ca0ea Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Thu, 7 May 2026 15:15:04 -0700 Subject: [PATCH] [Perf] Cap my_follows CTE at 200 in GetTracks/GetPlaylists The CTE feeds two consumers (followee_reposts, followee_favorites) that each emit at most 3 rows ordered by follower_count DESC. The existing LIMIT 5000 was non-binding for nearly every user and materialized far more rows than the LATERAL ever needs. Verified on the prod read replica with user 20 (1752 follows) and a 10-track id list, three warm runs each (PR 1 MATERIALIZED applied): LIMIT 5000: 86, 97, 92 ms (mean 92) LIMIT 200: 43, 31, 23 ms (mean 32) ~2.9x Edge case: a user whose only follower-of-X is ranked >200 by their own follower_count will no longer surface in followee_*. Acceptable trade-off: those low-fanout reposts are dominated by the top-200 in the social-proof rendering anyway. --- api/dbv1/get_playlists.sql.go | 3 ++- api/dbv1/get_tracks.sql.go | 6 +++++- api/dbv1/queries/get_playlists.sql | 3 ++- api/dbv1/queries/get_tracks.sql | 6 +++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/api/dbv1/get_playlists.sql.go b/api/dbv1/get_playlists.sql.go index 8e9c5984..04fde37e 100644 --- a/api/dbv1/get_playlists.sql.go +++ b/api/dbv1/get_playlists.sql.go @@ -24,7 +24,8 @@ WITH my_follows AS ( AND follower_user_id = $1 AND follows.is_delete = false ORDER BY follower_count DESC - LIMIT 5000 + -- See get_tracks.sql for rationale. + LIMIT 200 ) SELECT p.description, diff --git a/api/dbv1/get_tracks.sql.go b/api/dbv1/get_tracks.sql.go index f5ee3142..09592ef9 100644 --- a/api/dbv1/get_tracks.sql.go +++ b/api/dbv1/get_tracks.sql.go @@ -24,7 +24,11 @@ WITH my_follows AS ( AND follower_user_id = $1 AND follows.is_delete = false ORDER BY follower_count DESC - LIMIT 5000 + -- The two consumers (followee_reposts, followee_favorites) both + -- emit at most 3 rows ordered by follower_count DESC. Caring about + -- followees ranked >200 by follower_count is wasted work: they're + -- ~always dominated by the top-200 in social-proof terms. + LIMIT 200 ) SELECT t.track_id, diff --git a/api/dbv1/queries/get_playlists.sql b/api/dbv1/queries/get_playlists.sql index 4fe07d44..03324895 100644 --- a/api/dbv1/queries/get_playlists.sql +++ b/api/dbv1/queries/get_playlists.sql @@ -9,7 +9,8 @@ WITH my_follows AS ( AND follower_user_id = @my_id AND follows.is_delete = false ORDER BY follower_count DESC - LIMIT 5000 + -- See get_tracks.sql for rationale. + LIMIT 200 ) SELECT p.description, diff --git a/api/dbv1/queries/get_tracks.sql b/api/dbv1/queries/get_tracks.sql index 4702daaa..794766bc 100644 --- a/api/dbv1/queries/get_tracks.sql +++ b/api/dbv1/queries/get_tracks.sql @@ -9,7 +9,11 @@ WITH my_follows AS ( AND follower_user_id = @my_id AND follows.is_delete = false ORDER BY follower_count DESC - LIMIT 5000 + -- The two consumers (followee_reposts, followee_favorites) both + -- emit at most 3 rows ordered by follower_count DESC. Caring about + -- followees ranked >200 by follower_count is wasted work: they're + -- ~always dominated by the top-200 in social-proof terms. + LIMIT 200 ) SELECT t.track_id,