perf(webapp): paginate the environment variables settings page - #4597
Conversation
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details⏰ Context from checks skipped due to timeout. (7)
WalkthroughEnvironment-variable loading now supports server-side search and pagination. The presenter filters keys case-insensitively, sorts results by key, clamps the requested page, and returns pagination metadata. The route validates query parameters and passes them to the presenter. The page uses server-filtered results, resets pagination when searching, preserves search controls for empty matches, and displays pagination controls for multiple pages. A changelog entry documents the change. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
6572847 to
622d053
Compare
The env-var settings page loaded every variable in the project with a nested values read plus an unused valueReference (SecretReference) sub-load, so a project with many variables pulled variables x environments rows (~18k for large projects) in one burst on each page load. Paginate the presenter by variable key (count + orderBy key + skip/take, page size 50) and drop the never-read valueReference include. This bounds the value read to pageSize x environments per page, removes the SecretReference query entirely, and scopes the secret-value and updater lookups to the current page. Search moves server-side (key, case-insensitive) and the page gains pagination controls. All queries are index-backed: the (projectId, key) unique serves both the count and the ordered pagination (no sort), and the value/secret/user reads use existing indexes with page-scoped IN lists.
622d053 to
4f69315
Compare
What
The environment variables settings page loaded every variable in the project in one shot, with a nested
valuesread plus avalueReference(SecretReference) sub-load that was selected but never read. For a project with many variables this pulledvariables × environmentsvalue rows (~18k for large projects) on every page load, plus a matching ~18k-rowSecretReference INquery.This paginates the presenter by variable key and removes the dead include.
valueReference: { select: { key } }include → theSecretReferencequery is gone entirely.count+orderBy key+skip/take, page size 50 → the value read is bounded topageSize × environmentsper page.values: { some: { environmentId: { in } } }), sototalCount/totalPagesand theskip/takewindow match what actually renders (no phantom empty pages from variables that live only in archived branches or another member's dev env).orderBy: { key: "asc" }— the presenter no longer re-sorts each page withlocaleCompare, which under pagination could disagree with the DB collation at page boundaries.SecretStorekeys) and the updater lookup (userby id) are now scoped to the current page instead of the whole project.Why
The two correlated ~18k-row control-plane queries flagged in the ticket come from this settings-page presenter, not from any hot path. Both are index-covered (
rows_read == rows_returned); the issue is the sheer volume fetched in one burst. Bounding it per page removes the burst.Evidence
Measured on an isolated stack with a seeded project of 1000 variables × 3 environments (3000 value rows), using Prisma's emitted-SQL log:
countEXPLAINon Prisma's verbatim statements (index confirmed viaenable_seqscan=off; the local table is too small for the planner to choose them by default):count(WHERE projectId AND EXISTS(values in displayed envs)) → Hash Join: Index Scan onEnvironmentVariable_pkey+ Bitmap Index Scan onEnvironmentVariableValue_environmentId_idxWHERE projectId AND EXISTS(...) ORDER BY key LIMIT/OFFSET) → Nested Loop Semi Join: Index Scan onEnvironmentVariable_projectId_key_key(no Sort node) driving an Index-Only Scan onEnvironmentVariableValue_variableId_environmentId_keyvariableId = ANY … AND environmentId = ANY …) → index scan onEnvironmentVariableValue_environmentId_idxSecretStorekeys (key = ANY …) → index scan onSecretStore_key_idxNo new index required. Verified in the browser on the seeded project: 20 pages, page navigation, server-side search (matches across all pages), last page renders, no app console errors.
typecheck,oxlint,oxfmtall clean.Behavior change
The previous client-side search matched variable name and value (and environment type / branch name). Values are encrypted at rest and resolved separately, so they cannot be searched server-side under pagination. Search is now variable-name only, server-side, case-insensitive. Projects with fewer than one page of variables see no pagination bar and no visible change.
Rollout / rollback
Pure read-path change on a dashboard loader, no schema or data migration. Rollback is a straight revert.
Screenshots