Skip to content

perf(coderd): build the workspace build fan-out maps once per batch (#28074) - #29369

Open
jscottmiller wants to merge 1 commit into
release/2.34from
backport/28074-to-2.34
Open

jscottmiller wants to merge 1 commit into
release/2.34from
backport/28074-to-2.34

Conversation

@jscottmiller

Copy link
Copy Markdown
Contributor

Backport of #28074

Original PR: #28074 - perf(coderd): build the workspace build fan-out maps once per batch
Merge commit: 62f4afb
Requested by: @jscottmiller

Opened manually because the backport workflow's push was rejected by GitHub's workflow-scope check (run 34996286869). Cherry-pick applied cleanly; go build ./coderd/... and go test ./coderd -run TestConvertWorkspaceBuild pass on this branch. Addresses PLAT-386 / #27205.


Created with Coder Agents on behalf of @jscottmiller.

…28074)

`convertWorkspaceBuild` rebuilt seven maps from the caller's global
slices on every call and rescanned the provisioner daemon rows to filter
by job ID. `convertWorkspaceBuilds` calls it once per build with
identical slices, so map construction cost `O(builds x rows)` where
`O(rows)` suffices — quadratic in the number of workspaces on `GET
/api/v2/workspaces`.

The maps move into a `workspaceBuildIndex` built once per batch, keyed
exactly as before and now including daemons by job ID.
`convertWorkspaceBuild` takes the index instead of eight slices. Its
parent already hoisted `workspaceByID`, `jobByID`, and
`templateVersionByID` out of the same loop; this makes the rest
consistent.

Agents are sorted while the index is built, so a resource read by
several builds is sorted once rather than once per build. Same
comparator over the same rows, so the order is unchanged;
`TestConvertWorkspaceBuildsAgentOrder` covers it.

`BenchmarkConvertWorkspaceBuilds`, 5 resources x 2 agents x 4 apps per
build:

| builds | ns/op | B/op | allocs/op |
| --- | --- | --- | --- |
| 1 | 48.3k -> 48.1k | 121k -> 125k | 342 -> 359 |
| 25 | 12.7M -> 1.34M | 38.0MB -> 3.2MB | 69,621 -> 8,347 |
| 100 | 186M -> 5.67M | 596MB -> 13.0MB | 1,024,941 -> 33,080 |

Single-build conversion is a wash (one extra struct allocation); the
quadratic term is gone.

Addresses the map-allocation half of PLAT-386 / #27205. Bounding the
page size is separate (#28040) and does not remove this cost: at 100
workspaces per page it is still 100 passes over every resource, agent,
app, script, log source, status, and daemon row in the page.

---

Created with Coder Agents on behalf of @jscottmiller.

(cherry picked from commit 62f4afb)
@jscottmiller jscottmiller added the backport/v2.34 Backport PR targeting release/2.34 label Sep 15, 2026
@jscottmiller jscottmiller self-assigned this Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 Hey @jscottmiller!

This PR is targeting the release/2.34 release branch, but its title does not start with fix: or fix(scope):.

Only bug fixes should be cherry-picked to release branches. If this is a bug fix, please update the PR title to match the conventional commit format:

fix: description of the bug fix
fix(scope): description of the bug fix

If this is not a bug fix, it likely should not target a release branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/v2.34 Backport PR targeting release/2.34

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant