System Health Score
The dashboard displays a real-time system health score (0-100) that aggregates multiple health dimensions into a single at-a-glance indicator. The score is evaluated every 5 minutes by the HealthScoreService background service.
Health Components
Each component has a score (0-100), a weight that determines its influence on the overall score, and a status (Healthy, Warning, or Critical).
Core Server Components
| Component | Weight | What it checks |
|---|---|---|
| Certificates | 15% | TLS certificate expiry. Degrades at 60/30/7/0 days remaining. |
| Relay Sites | 15% | Unreachable sites (-20 each), pending sites (-10 each), outdated versions (-5 each). |
| Deployments | 15% | Failed deployments in the last 24 hours (-15 per failure). |
| Storage | 20% | Free disk space on the data drive. Degrades below 50/20/10/5 GB. |
| PXE Boot | 10% | Presence of required PXE boot files (bootmgfw.efi, BCD, boot.sdi, boot.wim). Proportional to files present. |
| License | 10% | License/trial validity. Healthy on a valid license or active trial; warns in the last 7 trial days and at 30/7 days before license expiry; critical when expired or locked. |
| Database | 15% | Database connectivity and response time. Degrades above 2000/5000 ms. |
Relay Server Components
Relay servers evaluate the same components except Relay Sites and License, replacing them with:
| Component | Weight | What it checks |
|---|---|---|
| Core Connection | 25% | Whether the relay can reach the Core server. Shows last heartbeat time when disconnected. |
| Connected Cache | 8% | MCC container state on relays where a cache has been deployed: Running = healthy, Deploying/Stopped = warning, deployment error = critical. Omitted entirely on relays without MCC, so it never penalizes sites that don't use the feature. |
Overall Score Calculation
The overall score is a weighted average of all component scores:
overall = sum(component.score * component.weight) / sum(component.weight)
| Score Range | Status | Dashboard Color |
|---|---|---|
| 80-100 | Healthy | Green |
| 50-79 | Warning | Yellow |
| 0-49 | Critical | Red |
Dashboard Display
The health card shows:
- Score ring - Circular progress indicator with the numeric score
- Status badge - Healthy, Warning, or Critical
- Component bars - Per-component score bars with icons
- Issues list - Collapsible section listing all detected issues across components
Relay Health on Core
Relay servers report their health score to Core via the heartbeat. The Core's Sites page displays each relay's health:
- Health column in the sites table - Score badge (green/yellow/red)
- Site detail panel - Health card showing score and status
This lets administrators monitor all relay health from the Core dashboard without visiting each relay individually.
Live health on the Dashboard
Separate from the weighted score, the Dashboard (/) carries a live drill-down for diagnosing why something is unhealthy. A row of topic pills sits under the alert hero, with a compact server picker (Core or any relay site) beside it. Clicking a pill opens that topic's detail below the row; clicking it again closes it, so a healthy dashboard stays a dashboard.
Every topic pill carries its own status dot, always visible, so one glance answers "is everything else green?" without opening anything:
| Dot | Meaning |
|---|---|
| Green | Healthy |
| Amber | Needs attention |
| Red | Failing |
| Grey | No data yet |
Topics are PXE, Boot Images, Relay Sync, Database, License, Certificates and Connected Cache. A pill is greyed out and unclickable when that topic is not reported for the selected server - relays report only PXE (fed by their heartbeat snapshot), and Connected Cache is greyed out when the feature is unlicensed or no relay site has a cache node enabled.
The Connected Cache topic answers both halves of "is my cache healthy and properly certified" in one place. It joins what Core provisioned (node status, issued certificate) with a live probe of each node's ports 80 and 443, because a cache node can be fully provisioned and still serve nothing a client can use - Delivery Optimization silently bypasses a node it cannot validate and downloads from Microsoft instead. Each row links straight to that site's Connected Cache tab.
The pills are the status overview and the attention list at the top of the page is the action list, so a topic issue is reported once, not twice. A topic that is merely warning shows only as a yellow dot here. A topic that is failing also gets a line in the attention list, linking down to its view - unless a health component issue up there already names the same topic, in which case that line wins because it carries the detail.
The page updates in real time when connected (a Live badge is shown under the title), falling back to 30-second polling otherwise. For Core, Poll health now rebuilds the snapshot immediately; for a relay, Request snapshot queues a force-sync so a fresh snapshot arrives on the next heartbeat. Selections are URL-addressable (/?server=...&topic=...) so a specific view can be bookmarked or shared. The old /healthhub address redirects here and keeps its query string.
Notifications
The health score service sends notifications when crossing thresholds:
| Threshold | Notification |
|---|---|
| Score drops below 50 | "System Health Degraded" - lists all warning/critical issues |
| Score drops below 25 | "System Health Critical" - lists all critical issues |
| Score recovers above 80 | Threshold resets (next drop will re-notify) |
Notifications use the system.healthScoreAlert event, which can be configured per-channel in Settings > Notifications > Events.
To avoid notification storms, the service tracks the last notified threshold and only sends when crossing a boundary (not on every evaluation cycle).