Why some alerts arrive in milliseconds and others in seconds
Motion alerts can be evaluated as soon as an event is created. AI and compiled
rules wait for indexed event context, and some also call a model. R4 in
docs/decisions.md records that split. This page explains the paths that ship
today.
Current runtime paths
NovaVMS currently has two alert-rule evaluation paths:
- Immediate legacy lane:
TopicEventCreatedruns the immediate evaluator for enabled, AI-freecamera_eventrules usingevent_category,trigger_topic_pattern, orsource_filter. Camera and gateway offline status changes run the system-event evaluator forcamera_offlineandgateway_offline. These paths writealert_historyand publishTopicAlertFiredwithout waiting for event indexing or a model. - Compiled/indexed lane:
TopicEventIndexedqueues active compiled versions for the compiled evaluator. It applies scope, recurring schedule/time-window, evidence, and optional contextual-judge predicates, then passes send decisions through NBD before publishingTopicAlertFired.
gateway_reconnect is not a supported system trigger; the create/update API
rejects it because the live evaluator handles offline transitions only.
Why the split exists
A single delayed pipeline forces a trade-off nobody wants. If every alert waits for AI, the sub-500ms target that motion triggers need to be useful for live monitoring is gone. If you fire every alert immediately, you never benefit from AI tags like “person-on-loading-dock-after-hours” — those tags do not exist until the AI call finishes.
Decision R4 captures the reason for the two paths:
- The immediate lane: predicates known when the event or supported offline status change arrives. No model call or indexing wait is required.
- The compiled/indexed lane: active compiled rules that need indexed evidence, time-window evaluation, or an optional contextual judge.
The two lanes do not read the same storage model: the immediate/system evaluators
read legacy alert_rules, while the compiled evaluator reads active
compiled_alert_rules versions.
What this means for you today
- Delivery time is path-dependent. AI-free legacy camera-event rules and supported offline system events do not wait for the AI/indexing lane. Compiled rules wait for event indexing, and contextual rules can also wait for a model call and queue capacity.
- If a compiled rule requires the contextual judge and the AI provider is down,
its degraded-policy behavior applies. The cloud emits a system event named
alerts.judge_queue_overflow(cloud/internal/alerts/judge_queue.go:151) for queue overflow. Thealerts.judge_budget_threshold_*family is separate — it fires when the per-org Gemini judge budget reaches 80 % or 100 % of the daily cap (cloud/internal/alerts/judge_budget.go:128), independent of provider health. Tune the daily cap at/settings/ai-budget. - The Events feed shows the event trigger time; the Alerts panel shows the alert dispatch time. The difference varies by evaluation path and queue state.
Where to go next
- Create an alert rule — how to write a rule that targets either lane
- Alert rule schema — fields that determine which lane a rule lands in
- Why NovaVMS uses a single AI call — what happens in the delayed lane before the alert fires