Skip to content

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: TopicEventCreated runs the immediate evaluator for enabled, AI-free camera_event rules using event_category, trigger_topic_pattern, or source_filter. Camera and gateway offline status changes run the system-event evaluator for camera_offline and gateway_offline. These paths write alert_history and publish TopicAlertFired without waiting for event indexing or a model.
  • Compiled/indexed lane: TopicEventIndexed queues 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 publishing TopicAlertFired.

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. The alerts.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