Backup Job Health · diff
git:20260728.b7e78fc to git:20260804.5567c51
11 added, 0 removed. Audit A to A.
---
name: "Backup Job Health"
description: >
Portfolio-wide backup job health across whatever BCDR and SaaS-backup tools
are connected: the two structurally different job models (image-based
appliance backup vs. SaaS-data snapshot backup) and how to normalize them
into one health record per protected unit, why a live consecutive-failure
streak matters more than a trailing success rate, the missed-versus-failed
distinction and its different root causes, and the two storage-trending
risk patterns (approaching capacity, anomalous growth).
when_to_use: >-
When assessing whether backup jobs are actually running successfully across
a portfolio, rather than checking one client's one appliance in isolation.
Use when: backup health, backup job failures, missed backups, backup
success rate, failed backup jobs, backup storage trending, is this client's
backups running, backup audit, backup job status.
---
# Backup Job Health
## Overview
"Backups are running" is the single most-assumed, least-verified fact in an MSP's
environment. A backup job that failed silently three nights ago looks identical, from
a distance, to one that's been succeeding for months — nobody notices until a restore
is needed and there's nothing current to restore from. This skill is the recurring,
portfolio-wide sweep that catches that gap before it becomes an incident: job success/
failure rate, missed-backup detection, and storage-consumption trending, rolled into
one normalized view across every backup and BCDR tool an org has connected.
This skill is about whether backups are *happening*. It is deliberately narrower than
disaster-recovery readiness as a whole — it does not assess whether a backup, once
taken, is actually recoverable (see `restore-test-verification`), and it does not
assess whether the retention window or cadence in place actually satisfies a
contracted requirement (see `retention-rpo-compliance`). Treat this as the first,
most frequent layer of the DR assurance stack: if jobs aren't running, nothing
downstream matters yet.
+ ## Anti-triggers
+
+ - **Backup Radar's own health records** — ScalePad already aggregates and
+ scores backup results across vendors; use `scalepad-backup-radar` when the
+ question is what that API returns. This skill normalizes across every
+ connected backup tool, including orgs that have no Backup Radar at all.
+ - **One platform's job, alert, or storage data** — use
+ `datto-bcdr-api-patterns`, `datto-saas-protection-api-patterns`,
+ `spanning-api-patterns`, or `unitrends-api-patterns` for a single vendor's
+ request shapes and field names.
+
## Key Concepts
### Two fundamentally different job models
Backup and BCDR vendors protect data in two structurally different ways, and treating
them as the same "job" concept produces misleading comparisons:
- **Image-based appliance backup** (e.g. Datto BCDR / SIRIS / Alto, Unitrends) —
protects physical or virtual servers/workstations by taking periodic block-level
or image-level snapshots to a local appliance, then syncing offsite/to the cloud.
A "job" here is a scheduled backup of one protected agent/asset on one appliance.
Health signals include: last successful local backup, last successful offsite
sync, and (for Datto BCDR specifically) screenshot/boot verification status —
see `restore-test-verification`.
- **SaaS-data snapshot backup** (e.g. Datto SaaS Protection, Spanning) — protects
cloud application data (Microsoft 365 mailboxes/OneDrive/SharePoint/Teams, Google
Workspace, Salesforce) by taking periodic API-level snapshots of tenant data. A
"job" here is a scheduled backup pass across a set of protected seats/users for a
tenant. There is no "appliance" and no local/offsite sync distinction — health
signals are seat coverage (are all licensed users actually being backed up) and
per-run success/failure across the tenant.
Normalize both into a single health record per protected unit (appliance-agent pair,
or tenant-seat set) with the same fields — last successful run, run status, and
failure streak — even though the underlying job mechanics differ. Don't force a
one-size-fits-all metric like "backup window duration" that only makes sense for one
model.
### Job success/failure rate
For each protected unit, compute the success rate over a rolling window (default:
last 30 days unless the org has a documented preference) and, more importantly, the
**current consecutive-failure streak**. A unit with a 96% success rate over 30 days
but a live 4-night failure streak right now is a more urgent problem than a unit with
90% success and no current streak — trailing averages hide exactly the thing that
matters most: is it broken *right now*.
### Missed-backup detection
A missed backup is distinct from a failed backup: a failed backup ran and errored; a
missed backup never ran at all (no job execution recorded for the expected window).
Both matter, but they point to different root causes — a failed job usually means an
in-scope problem (disk full, credential expired, source unreachable), while a missed
job often means a scheduling, licensing, or connectivity problem that's more
structural (the agent/connector isn't checking in at all). Report them as separate
categories rather than merging them into one "unhealthy" bucket, since the
remediation path differs.
### Storage-consumption trending
Track local and offsite/cloud storage consumption per appliance (or per SaaS tenant,
where the vendor exposes storage/quota data) over time. Flag two distinct risk
patterns:
- **Approaching capacity** — an appliance trending toward its local storage limit,
which risks retention truncation (older recovery points get purged early to make
room) even while nightly jobs continue to report success. This is a silent
retention risk — see `retention-rpo-compliance` for how a storage-forced retention
cut interacts with a contracted retention requirement.
- **Anomalous growth** — a sudden, unexplained jump in daily change-rate/storage
consumption, which can indicate anything from a legitimate data-growth event to
ransomware encryption activity happening on the protected source. Anomalous growth
is worth flagging even when it isn't yet a capacity problem, because of what it
might indicate about the protected system.
### If no backup/BCDR tool is connected
State plainly that job health cannot be assessed: "No backup or BCDR connector is
connected through the gateway, so there's no backup job data to audit." Do not
fabricate success rates, job counts, or storage figures.
## Common Workflows
### Full portfolio sweep
1. Discover connected backup/BCDR tools via `conduit__search_tools` — don't assume
which of Datto BCDR, Datto SaaS Protection, Spanning, or Unitrends (or others) are
live for this org.
2. For each connected tool, pull the protected-unit list (appliances/agents for
image-based tools; tenants/seats for SaaS-snapshot tools) and each unit's recent
job history.
3. Normalize into one health record per protected unit: last successful run, current
run status, consecutive-failure streak, and (where available) storage/quota state.
4. Bucket into: actively failing (current failure streak), missed (no run recorded
for expected window), storage-at-risk, and healthy.
5. Report worst-first: longest active failure streak, then missed backups, then
storage risk.
### Targeted client check
1. Resolve the client to its protected units across whatever connected tool(s) cover
them (a client may have both an on-prem appliance and a SaaS-backup tenant).
2. Pull and normalize job history for just that client's units.
3. Report success/failure rate, active streaks, and storage state for that client
only.
## Error Handling
- **No backup/BCDR connector connected:** stop and say so; do not fabricate job
status.
- **A connected tool doesn't expose storage/quota data:** report job success/failure
normally and mark the storage-trending section "unable to verify — connector does
not expose storage data" rather than omitting it silently.
- **A protected unit exists in inventory but has no job history at all:** treat this
as a missed backup, not a gap in the report — a never-run job is exactly the kind
of silent failure this skill exists to catch.
## Best Practices
- State the rolling window used (default 30 days) explicitly in every report.
## Related Skills
- [Restore-Test Verification](../restore-test-verification/SKILL.md) — whether a
successfully-run backup is actually recoverable; this skill only confirms the job
ran, not that its output is usable.
- [Retention/RPO Compliance](../retention-rpo-compliance/SKILL.md) — whether the
retention window and backup cadence in place satisfy a contracted requirement;
relevant when storage-forced retention truncation is detected here.