@@ -361,15 +361,23 @@ func (c *StoreReconciler) ReconcilePreset(ctx context.Context, ps prebuilds.Pres
361
361
slog .F ("preset_name" , ps .Preset .Name ),
362
362
)
363
363
364
- // Report a preset as hard-limited only if all the following conditions are met:
365
- // - The preset is marked as hard-limited
366
- // - The preset is using the active version of its template, and the template has not been deleted
364
+ // Report a metric only if the preset uses the latest version of the template and the template is not deleted.
365
+ // This avoids conflicts between metrics from old and new template versions.
367
366
//
368
- // The second condition is important because a hard-limited preset that has become outdated is no longer relevant.
369
- // Its associated prebuilt workspaces were likely deleted, and it's not meaningful to continue reporting it
370
- // as hard-limited to the admin.
371
- reportAsHardLimited := ps .IsHardLimited && ps .Preset .UsingActiveVersion && ! ps .Preset .Deleted
372
- c .metrics .trackHardLimitedStatus (ps .Preset .OrganizationName , ps .Preset .TemplateName , ps .Preset .Name , reportAsHardLimited )
367
+ // NOTE: Multiple versions of a preset can exist with the same orgName, templateName, and presetName,
368
+ // because templates can have multiple versions — or deleted templates can share the same name.
369
+ //
370
+ // The safest approach is to report the metric only for the latest version of the preset.
371
+ // When a new template version is released, the metric for the new preset should overwrite
372
+ // the old value in Prometheus.
373
+ //
374
+ // However, there’s one edge case: if an admin creates a template, it becomes hard-limited,
375
+ // then deletes the template and never creates another with the same name,
376
+ // the old preset will continue to be reported as hard-limited —
377
+ // even though it’s deleted. This will persist until `coderd` is restarted.
378
+ if ps .Preset .UsingActiveVersion && ! ps .Preset .Deleted {
379
+ c .metrics .trackHardLimitedStatus (ps .Preset .OrganizationName , ps .Preset .TemplateName , ps .Preset .Name , ps .IsHardLimited )
380
+ }
373
381
374
382
// If the preset reached the hard failure limit for the first time during this iteration:
375
383
// - Mark it as hard-limited in the database
0 commit comments