fix(monitoring): raise VeleroBackupStale from 30h to 60h #658

Merged
k.renner merged 1 commits from velero-stale-60h into master 2026-08-27 07:36:12 +00:00
Member

At 30h a single missed cycle pages critical — and a single missed cycle is the normal cost of touching the nodes. Velero moves data through pods, so draining a node kills whatever upload is in flight and the schedule is lost for that day; it is not retried. Backup windows run 03:15–08:45 UTC, so any rolling node work overlapping them produces a guaranteed critical alert per affected schedule.

That is noise about planned work, not signal about backups. It fired for eleven schedules during the bare-metal Talos upgrade and again today.

60h still catches what the rule exists for. Two consecutive failures is no longer explicable by one maintenance window. Nothing is hidden in the meantime: VeleroBackupFailed fires on the first failure regardless, so the first cycle stays visible — only the escalation to critical waits for a second cycle to confirm it.

Calibration against the current state:

home-assistant-daily  48.5 h
netbird-backup-daily  47.8 h
trmnl-daily           47.3 h
wordpress-daily       46.8 h

The new threshold leaves those roughly twelve hours — exactly until today's runs. If those fail too, the alert fires. That is the intended behaviour, not a gap.

Verified: passes a server-side dry run; the expression returns nothing at 60h; and the same query at a lower bound returns the four affected schedules with their ages, so the selector is known to match rather than merely silent.

Context on why this came up: over 30 days each schedule has failed exactly once (home-assistant twice), all on the bare-metal upgrade day and today. The failures are node-disruption artefacts — dial tcp 10.96.0.1:443: no route to host during control-plane reboots on the first day, killed DataUploads on a drained node today.

At 30h a **single** missed cycle pages critical — and a single missed cycle is the normal cost of touching the nodes. Velero moves data through pods, so draining a node kills whatever upload is in flight and the schedule is lost for that day; it is not retried. Backup windows run 03:15–08:45 UTC, so any rolling node work overlapping them produces a guaranteed critical alert per affected schedule. That is noise about planned work, not signal about backups. It fired for eleven schedules during the bare-metal Talos upgrade and again today. **60h still catches what the rule exists for.** Two consecutive failures is no longer explicable by one maintenance window. Nothing is hidden in the meantime: `VeleroBackupFailed` fires on the first failure regardless, so the first cycle stays visible — only the escalation to critical waits for a second cycle to confirm it. **Calibration against the current state:** ``` home-assistant-daily 48.5 h netbird-backup-daily 47.8 h trmnl-daily 47.3 h wordpress-daily 46.8 h ``` The new threshold leaves those roughly twelve hours — exactly until today's runs. If those fail too, the alert fires. That is the intended behaviour, not a gap. **Verified:** passes a server-side dry run; the expression returns nothing at 60h; and the same query at a lower bound returns the four affected schedules with their ages, so the selector is known to match rather than merely silent. Context on why this came up: over 30 days each schedule has failed exactly once (home-assistant twice), all on the bare-metal upgrade day and today. The failures are node-disruption artefacts — `dial tcp 10.96.0.1:443: no route to host` during control-plane reboots on the first day, killed DataUploads on a drained node today.
claude-bot added 1 commit 2026-08-27 07:35:35 +00:00
fix(monitoring): raise VeleroBackupStale from 30h to 60h
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
e2f3d67f79
At 30h a single missed cycle pages critical, and a single missed cycle is the
normal cost of touching the nodes. Velero moves data through pods, so draining
a node kills whatever upload is in flight and the schedule is lost for that day
— it is not retried. Backup windows run 03:15 to 08:45 UTC, so any rolling node
work overlapping them produced a guaranteed critical alert per affected
schedule.

That is noise about planned work, not signal about backups. It fired for eleven
schedules during the bare-metal Talos upgrade and again today.

60h still catches what the rule exists for. Two consecutive failures is no
longer explicable by one maintenance window. Nothing is hidden in the meantime:
VeleroBackupFailed fires on the first failure regardless, so the first cycle is
still visible — only the escalation to critical waits for a second cycle to
confirm it.

Calibration against the current state: the four stale schedules sit at 46.8 to
48.5 hours since their last success, so the new threshold leaves roughly twelve
hours — exactly until today's runs. If those fail too, the alert fires, which
is the intended behaviour rather than a gap.

Verified: the rule passes a server-side dry run, the expression returns nothing
at 60h, and the same query at a lower bound returns the four affected schedules
with their ages — so the selector is known to match rather than merely silent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
k.renner merged commit 5f8c0115b5 into master 2026-08-27 07:36:12 +00:00
review-bot left a comment
Member

🤖 Automated review — model claude-haiku-4-5-20251001 (complexity: trivial), commit e2f3d67f79200d04d97de3bb92f4b2f67e4ea031.

Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.


Summary

This PR raises the VeleroBackupStale alert threshold from 30 hours to 60 hours in the Prometheus monitoring rules. The change is well-reasoned: at 30h a single missed backup triggers a critical alert, but single missed cycles are normal during node maintenance (draining nodes kills in-flight Velero uploads). By moving to 60h, the alert now requires evidence of two consecutive failed backup cycles, which cannot be explained by a single maintenance window. The PR includes thorough documentation of the rationale and verification via dry-run testing.

🟢 Nits

Line 62: The arithmetic 60 * 3600 is correct (216,000 seconds = 60 hours), though using a named constant like ONE_HOUR_SECONDS in a Prometheus template could improve clarity for future maintainers. That said, this is minor and consistent with how the backup window is expressed in comments (03:15–08:45 UTC as concrete times rather than offsets).

Tests

The PR body documents verification: server-side dry run passed, the expression returns nothing at 60h (no false positives among current backups), and queries at lower bounds confirm the selector matches the four affected schedules with their current ages. This is solid testing for a monitoring rule change. No additional tests needed — Prometheus rules are validated by the cluster's Prometheus instance on deployment.

Recommendation

Looks reasonable — no blocking issues; comment above is optional.

🤖 **Automated review** — model `claude-haiku-4-5-20251001` (complexity: trivial), commit `e2f3d67f79200d04d97de3bb92f4b2f67e4ea031`. > Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review. --- ## Summary This PR raises the `VeleroBackupStale` alert threshold from 30 hours to 60 hours in the Prometheus monitoring rules. The change is well-reasoned: at 30h a single missed backup triggers a critical alert, but single missed cycles are normal during node maintenance (draining nodes kills in-flight Velero uploads). By moving to 60h, the alert now requires evidence of two consecutive failed backup cycles, which cannot be explained by a single maintenance window. The PR includes thorough documentation of the rationale and verification via dry-run testing. ## 🟢 Nits **Line 62**: The arithmetic `60 * 3600` is correct (216,000 seconds = 60 hours), though using a named constant like `ONE_HOUR_SECONDS` in a Prometheus template could improve clarity for future maintainers. That said, this is minor and consistent with how the backup window is expressed in comments (03:15–08:45 UTC as concrete times rather than offsets). ## Tests The PR body documents verification: server-side dry run passed, the expression returns nothing at 60h (no false positives among current backups), and queries at lower bounds confirm the selector matches the four affected schedules with their current ages. This is solid testing for a monitoring rule change. No additional tests needed — Prometheus rules are validated by the cluster's Prometheus instance on deployment. ## Recommendation Looks reasonable — no blocking issues; comment above is optional. <!-- pr-review:sha=e2f3d67f79200d04d97de3bb92f4b2f67e4ea031 -->
Sign in to join this conversation.