diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index 3b2f0844fa5..98a7cf204c6 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -313,8 +313,7 @@ func subscribeToFolderChanges(logger log.Logger, bus bus.Bus, dbStore api.RuleSt // Run starts the scheduler and Alertmanager. func (ng *AlertNG) Run(ctx context.Context) error { - ng.Log.Debug("Starting") - ng.stateManager.Warm(ctx, ng.store) + ng.Log.Debug("Starting", "execute_alerts", ng.Cfg.UnifiedAlerting.ExecuteAlerts) children, subCtx := errgroup.WithContext(ctx) @@ -330,6 +329,17 @@ func (ng *AlertNG) Run(ctx context.Context) error { }) if ng.Cfg.UnifiedAlerting.ExecuteAlerts { + // Only Warm() the state manager if we are actually executing alerts. + // Doing so when we are not executing alerts is wasteful and could lead + // to misleading rule status queries, as the status returned will be + // always based on the state loaded from the database at startup, and + // not the most recent evaluation state. + // + // Also note that this runs synchronously to ensure state is loaded + // before rule evaluation begins, hence we use ctx and not subCtx. + // + ng.stateManager.Warm(ctx, ng.store) + children.Go(func() error { return ng.schedule.Run(subCtx) })