fix: reduce impact of GetPrebuildMetrics on database (#19694)

see https://github.com/coder/internal/issues/959 but the tl; dr is:
- we call this DB query on an interval (every 15s) and it would be
called on each coderd replica as well
- the generated values update very infrequently (for our most used
internal template I saw the builds created/claimed update twice in a 1h
period)
- we have no index on the initiator ID, so this query has to scan the
entire workspace_builds table on every request

In reality this should likely just be a Prometheus metric, and
Prometheus can handle the counter reset behaviour at query time, but for
now this should at least cut the load of the query to 25% of it's
current impact.

---------

Signed-off-by: Callum Styan <callumstyan@gmail.com>
This commit is contained in:
Callum Styan
2025-09-04 13:43:50 -07:00
committed by GitHub
parent 20309074d1
commit 0ec9df390b
4 changed files with 11 additions and 1 deletions
+2
View File
@@ -2939,6 +2939,8 @@ CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE (de
CREATE INDEX idx_workspace_app_statuses_workspace_id_created_at ON workspace_app_statuses USING btree (workspace_id, created_at DESC);
CREATE INDEX idx_workspace_builds_initiator_id ON workspace_builds USING btree (initiator_id);
CREATE UNIQUE INDEX notification_messages_dedupe_hash_idx ON notification_messages USING btree (dedupe_hash);
CREATE UNIQUE INDEX organizations_single_default_org ON organizations USING btree (is_default) WHERE (is_default = true);
@@ -0,0 +1,2 @@
-- Remove index on workspace_builds.initiator_id
DROP INDEX IF EXISTS idx_workspace_builds_initiator_id;
@@ -0,0 +1,6 @@
-- Add index on workspace_builds.initiator_id to optimize prebuild queries
-- This will dramatically improve performance for:
-- - GetPrebuildMetrics (called every 15 seconds)
-- - Any other queries using workspace_prebuild_builds view
-- - Provisioner job queue prioritization
CREATE INDEX idx_workspace_builds_initiator_id ON workspace_builds (initiator_id);
@@ -105,7 +105,7 @@ var (
)
const (
metricsUpdateInterval = time.Second * 15
metricsUpdateInterval = time.Second * 60
metricsUpdateTimeout = time.Second * 10
)