From 8230090b6dfbc74a2fec89b694cd270f952b6e49 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Thu, 8 Jan 2026 20:28:27 -0800 Subject: [PATCH] perf(desktop): fix N+1 query in getAllGrouped workspace procedure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preload all worktrees once and use already-loaded project data from groupsMap instead of calling getWorkspacePath per workspace, which was causing N additional DB queries (one per workspace). Before: 2 + N queries (where N = number of workspaces) After: 3 queries (constant) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../routers/workspaces/procedures/query.ts | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts b/apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts index 748aef27b73..f7d2dedb789 100644 --- a/apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts +++ b/apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts @@ -7,6 +7,8 @@ import { getWorkspace } from "../utils/db-helpers"; import { detectBaseBranch, hasOriginRemote } from "../utils/git"; import { getWorkspacePath } from "../utils/worktree"; +type WorktreePathMap = Map; + export const createQueryProcedures = () => { return router({ get: publicProcedure @@ -34,6 +36,12 @@ export const createQueryProcedures = () => { .where(isNotNull(projects.tabOrder)) .all(); + // Preload all worktrees once to avoid N+1 queries in the loop below + const allWorktrees = localDb.select().from(worktrees).all(); + const worktreePathMap: WorktreePathMap = new Map( + allWorktrees.map((wt) => [wt.id, wt.path]), + ); + const groupsMap = new Map< string, { @@ -84,11 +92,20 @@ export const createQueryProcedures = () => { .sort((a, b) => a.tabOrder - b.tabOrder); for (const workspace of allWorkspaces) { - if (groupsMap.has(workspace.projectId)) { - groupsMap.get(workspace.projectId)?.workspaces.push({ + const group = groupsMap.get(workspace.projectId); + if (group) { + // Resolve path from preloaded data instead of per-workspace DB queries + let worktreePath = ""; + if (workspace.type === "worktree" && workspace.worktreeId) { + worktreePath = worktreePathMap.get(workspace.worktreeId) ?? ""; + } else if (workspace.type === "branch") { + worktreePath = group.project.mainRepoPath; + } + + group.workspaces.push({ ...workspace, type: workspace.type as "worktree" | "branch", - worktreePath: getWorkspacePath(workspace) ?? "", + worktreePath, isUnread: workspace.isUnread ?? false, }); }