Anomaly Detection
Decision logic
The detection engine runs once per hour. For each beet, it:
- Counts events received in the current hour (from
HH:00:00toHH:59:59UTC) - Fetches the baseline for this hour × day-of-week from
beet_baselines_hourly - Compares the actual count to the expected range
Severity thresholds
| Severity | Condition |
|---|---|
| Healthy | Count within the expected range |
| Warning | Count below avg - 1.5 × stddev |
| Critical | Count below avg - 2.5 × stddev, or zero events when average > 0 |
The multipliers (1.5 and 2.5) are chosen to produce a low false-positive rate in practice. They are not currently user-configurable (custom thresholds are a Pro+ roadmap item).
Cold-start handling
If a beet has never received any events in the current hour historically, Heartbeet cannot compute a meaningful expected range. Two sub-cases:
- Learning period not complete (< 14 days): no alert fires
- Zero historical events, zero actual events: treated as healthy (absence is expected)
- Zero historical events, actual events present: baseline is seeded from current data and no alert fires
Complete silence
If a beet expected events (avg > 0) and received zero this hour, the severity is always Critical — regardless of standard deviation. Silence is always a signal.
Alert lifecycle
┌─────────────────────────────────┐
Healthy ───────▶│ count < warning threshold │──▶ Alert opened (warning)
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ count < critical threshold │──▶ Severity escalated (critical)
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ count recovers to normal range │──▶ Alert resolved
└─────────────────────────────────┘An alert is represented as a row in anomaly_alerts with a status of open or resolved.
What triggers resolution
An alert is resolved when the current hour’s event count returns within the expected range. Heartbeet resolves automatically — you do not need to acknowledge or close alerts manually.
When an alert resolves, a resolved notification is sent via all configured alert channels.