feat: improve templates list sorting#2983
Open
drankou wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Code Review
I have reviewed the code changes and have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
❌ 2 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
fbe564f to
0eecb69
Compare
…sort and filter The name/cpu/memory sort variants resolved each template's default build through per-template laterals with an OR spanning envs and env_defaults, which is not sargable - Postgres seq-scanned all of envs (~96M rows, only ~1M templates) on every page, taking ~70s regardless of team size. A template can have many tagged builds, each with its own latest build, so a single cpu/memory value per template row is ambiguous anyway. Sorting and filtering by build fields is dropped from the endpoint entirely; build columns remain display-only, resolved for the returned page via a lateral. The remaining sorts (name, created_at, updated_at) use two keyset-paginated CTE branches (team templates + shared default templates), each with its own ORDER BY and LIMIT, merged with UNION. updated_at gets a partial index (team_id, updated_at DESC, id DESC) WHERE source = 'template' (~118 MB vs ~12 GB unfiltered, hypopg-estimated), making it index-driven like created_at: 9s cold / 0.4s warm -> ms on the largest (370k-template) team.
0eecb69 to
15b62ba
Compare
The name sort key lives in env_aliases, so each page pays a per-template lateral over the whole team: ~2.1s per page on the largest (370k-template) team even with all pages cached, since the cost is the ~370k aggregate probes rather than I/O. Finding a template by name is served by the search filter; alphabetical browsing does not justify keeping the one remaining O(team size) query in the endpoint. With this, every supported sort (created_at, updated_at) is an index-driven top-N scan.
564de0d to
e891cbf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes ENG-4207
Problem
Templates list took very long in prod for any team when sorting by name/cpu/memory: a non-sargable OR across envs/env_defaults forced a seq scan of all envs rows, and build-field sorts resolved every template's default build through env_build_assignments/env_builds laterals — O(team size) per page.
Changes
Drop cpu/memory sort + filter from the endpoint. With multiple tags per template, a single build value per row is an arbitrary pick anyway (team decision: resource columns belong on the builds page). Build fields in the response stay, display-only, resolved per returned page.
Drop name sort. Sort key lives in
env_aliases→ per-template lateral, taking too long on the largest teams. Search covers find-by-name UX.Rewrite
created_at/updated_atsorts as keyset-paginated UNION of two CTE branches (team templates + shared defaults), each index-driven.New migration: partial index
(team_id, updated_at DESC, id DESC) WHERE source = 'template'— cover updated_at sort