fix: limit the scope of the template average build time query to the last 100 (#19648)

This PR should resolve https://github.com/coder/internal/issues/719 by
limiting the `workspace_builds` rows selected by the query to the most
recent 100 builds of a template, as opposed to all builds in the last
30d. For our own internal templates with the most builds (1700-2000 in a
30d period) this should cut the query execution time by about 80%.

Unless we have some restriction on keeping the 30d period, contract
related or otherwise, this seems like a safe change to make. In addition
to the execution speed improvements it also means the memory for the
query is bounded as well.

If we want to keep a 30d time period for the avg build time value I
think it's worth exploring a purpose built solution such as histogram
structures where the build times could be bucketized by template ID as
they're observed.

---------

Signed-off-by: Callum Styan <callumstyan@gmail.com>
This commit is contained in:
Callum Styan
2025-09-01 09:31:21 -07:00
committed by GitHub
parent 6574299fcc
commit 4fab14b40b
8 changed files with 15 additions and 24 deletions
+3 -8
View File
@@ -11903,11 +11903,11 @@ JOIN provisioner_jobs pj ON
WHERE
template_versions.template_id = $1 AND
(pj.completed_at IS NOT NULL) AND (pj.started_at IS NOT NULL) AND
(pj.started_at > $2) AND
(pj.canceled_at IS NULL) AND
((pj.error IS NULL) OR (pj.error = ''))
ORDER BY
workspace_builds.created_at DESC
LIMIT 100
)
SELECT
-- Postgres offers no clear way to DRY this short of a function or other
@@ -11921,11 +11921,6 @@ SELECT
FROM build_times
`
type GetTemplateAverageBuildTimeParams struct {
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
StartTime sql.NullTime `db:"start_time" json:"start_time"`
}
type GetTemplateAverageBuildTimeRow struct {
Start50 float64 `db:"start_50" json:"start_50"`
Stop50 float64 `db:"stop_50" json:"stop_50"`
@@ -11935,8 +11930,8 @@ type GetTemplateAverageBuildTimeRow struct {
Delete95 float64 `db:"delete_95" json:"delete_95"`
}
func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg GetTemplateAverageBuildTimeParams) (GetTemplateAverageBuildTimeRow, error) {
row := q.db.QueryRowContext(ctx, getTemplateAverageBuildTime, arg.TemplateID, arg.StartTime)
func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, templateID uuid.NullUUID) (GetTemplateAverageBuildTimeRow, error) {
row := q.db.QueryRowContext(ctx, getTemplateAverageBuildTime, templateID)
var i GetTemplateAverageBuildTimeRow
err := row.Scan(
&i.Start50,