The alerts jobs run every 15 to 60 seconds, so their statement count is a host's constant database load. StatementBudgetTest counts the statements of each job and polled request and fails when they grow with the rows held. Measured with the same scenarios before (0.1.0-RC.18) and after: - alertsEscalateAndRemind, 50 open alerts, nothing due: 452 -> 1. It reads only alerts a reminder or an escalation policy can apply to, decides from the row and the reference tables, and takes the per-alert transaction only when something may be due. An alert with nothing due is not written, so timedNotificationCheckedAt is the last attempt, not the last tick. - alertsEvaluateMonitors: 20 monitors not due 5 -> 2 (due monitors selected in SQL, upkeep in one read); 20 due clean monitors 185 -> 84; a per-record monitor refreshing 10 alerts 205 -> 120. - alertsDeliverNotifications: idle 9 -> 7; 60 pending deliveries in 2 groups 317 -> 22; the purge runs hourly instead of every tick. - Queued producer signals are recorded in batches: 200 resolves for alerts that are not open plus 50 heartbeats 369 -> about 33. A repeated raise of an open alert 17 -> 10. AlertsReferenceCache holds alert types, groups, escalation policies, steps and enabled mutes in a core Memoization registered with core ClusterCaches. A record-change listener clears a table on every node (ClusterBus) when it is written through QQQ; entries expire after 60 seconds; a table over 2,000 rows is not held. A type's openCount and lastRaisedAt are engine counters: they do not clear the cache and are no longer record-audited. Changeset 55 adds ix_alerts_alert_flapping for the upkeep read. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>