fix: exclude provisioner_state from workspace_build_with_user view (#22159)

The provisioner state for a workspace build was being loaded for every
long-lived agent rpc connection. Since this state can be anywhere from
kilobytes to megabytes this can gradually cause the `coderd` memory
footprint to grow over time. It's also a lot of unnecessary allocations
for every query that fetches a workspace build since only a few callers
ever actually reference the provisioner state.

This PR removes it from the returned workspace build and adds a query to
fetch the provisioner state explicitly.
This commit is contained in:
Jon Ayers
2026-02-23 22:46:17 -06:00
committed by GitHub
parent bf076fb7ee
commit 0a7a3da178
27 changed files with 379 additions and 90 deletions
@@ -0,0 +1,31 @@
-- Restore provisioner_state to workspace_build_with_user view.
DROP VIEW workspace_build_with_user;
CREATE VIEW workspace_build_with_user AS
SELECT
workspace_builds.id,
workspace_builds.created_at,
workspace_builds.updated_at,
workspace_builds.workspace_id,
workspace_builds.template_version_id,
workspace_builds.build_number,
workspace_builds.transition,
workspace_builds.initiator_id,
workspace_builds.provisioner_state,
workspace_builds.job_id,
workspace_builds.deadline,
workspace_builds.reason,
workspace_builds.daily_cost,
workspace_builds.max_deadline,
workspace_builds.template_version_preset_id,
workspace_builds.has_ai_task,
workspace_builds.has_external_agent,
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS initiator_by_username,
COALESCE(visible_users.name, ''::text) AS initiator_by_name
FROM
workspace_builds
LEFT JOIN
visible_users ON workspace_builds.initiator_id = visible_users.id;
COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
@@ -0,0 +1,33 @@
-- Drop and recreate workspace_build_with_user to exclude provisioner_state.
-- This avoids loading the large Terraform state blob (1-5 MB per workspace)
-- on every query that uses this view. The callers that need provisioner_state
-- now fetch it separately via GetWorkspaceBuildProvisionerStateByID.
DROP VIEW workspace_build_with_user;
CREATE VIEW workspace_build_with_user AS
SELECT
workspace_builds.id,
workspace_builds.created_at,
workspace_builds.updated_at,
workspace_builds.workspace_id,
workspace_builds.template_version_id,
workspace_builds.build_number,
workspace_builds.transition,
workspace_builds.initiator_id,
workspace_builds.job_id,
workspace_builds.deadline,
workspace_builds.reason,
workspace_builds.daily_cost,
workspace_builds.max_deadline,
workspace_builds.template_version_preset_id,
workspace_builds.has_ai_task,
workspace_builds.has_external_agent,
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS initiator_by_username,
COALESCE(visible_users.name, ''::text) AS initiator_by_name
FROM
workspace_builds
LEFT JOIN
visible_users ON workspace_builds.initiator_id = visible_users.id;
COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';