Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
jscottmiller merged 5 commits into
mainfrom
scott/plat-386-workspace-build-fanout
Aug 18, 2026
Merged

perf(coderd): build the workspace build fan-out maps once per batch#28074
jscottmiller merged 5 commits into
mainfrom
scott/plat-386-workspace-build-fanout

Conversation

@jscottmiller

Copy link
Copy Markdown
Contributor

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.

convertWorkspaceBuild rebuilt seven maps from the caller's global slices
on every call and rescanned the provisioner daemon rows, so
convertWorkspaceBuilds paid that cost once per build over the same rows.

The maps move into a workspaceBuildIndex built once per batch, keyed as
before and now including daemons by job ID. Agents are sorted while the
index is built, so a resource read by several builds is sorted once
rather than once per build; the comparison and the rows are unchanged, so
the order is the same.
@linear-code

linear-code Bot commented Aug 12, 2026

Copy link
Copy Markdown

PLAT-386

…ortFunc

The aliasing note claimed the index maps aliased the input slices, but each
bucket is a freshly allocated slice of copied rows. The agent sort comment
described a resource shared by several builds, which cannot happen because
resources are grouped by job ID and each build has its own job.

Document that conversion reorders bucket contents in place, and replace
sort.Slice with slices.SortFunc.
…nversion

The batch conversion reads one index for every build, so cover the rows each
build receives: resource count and job ID, build-scoped resource, agent and app
names, metadata, scripts, log sources and per-app statuses. Add a build with no
eligible daemon rows alongside builds that have them, and a case where agents
share a display order so the name comparison runs.
Keep the two facts the field names do not carry: buckets are reordered in
place during conversion, and the input slices are not modified or aliased.
Row counts and the resource job ID already pin the index keying, so drop the
resource and agent name prefixes and the assertions on fixture field values,
which cover conversion of individual rows rather than how rows are grouped.
@jscottmiller
jscottmiller marked this pull request as ready for review August 17, 2026 18:32

@BobbyHo BobbyHo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice memory optimization. LGTM.

@jscottmiller
jscottmiller merged commit 62f4afb into main Aug 18, 2026
56 of 59 checks passed
@jscottmiller
jscottmiller deleted the scott/plat-386-workspace-build-fanout branch August 18, 2026 16:33
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants