CloudWatch dashboards nobody has opened in 45 days
What does ZopNight detect here?
ZopNight reviews a CloudWatch dashboard when its last captured GetDashboard view is at least 45 days old and the dashboard carries a real charge. Dashboards are free up to 3 per account, roughly $3 a month after that. Never-viewed dashboards abstain, because absent view data cannot justify a guided delete.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-094 |
| Category | orphan |
| Severity | low |
| Metric | none — pure configuration read |
| Source | cloudwatch_dashboard.go |
Where it applies
The fourth dashboard is where billing starts
CloudWatch gives every account 3 dashboards free. From the fourth onward each one carries a standing per-dashboard charge, around $3 a month, that accrues whether anyone opens it or not. Old project dashboards and experiment leftovers are the usual suspects. Because the free tier covers the common case, a dashboard with zero billed cost is deliberately never flagged: the delete lever recovers a real dollar or the rule stays quiet.
How a dashboard view becomes a signal
There is no “last viewed” field on a dashboard. The rule derives it: the aggregator captures GetDashboard read events per dashboard and keeps the most recent one, and staleness is the age of that latest view. No captured view at all means the rule abstains, fail-closed, because “no views” is indistinguishable from “no data, no permission, or created after the window”, and a guided delete must never rest on an unprovable “unused”.
A 45-day staleness bar inside a 90-day memory
The threshold is 45 days without a view. The activity feed the rule reads retains roughly 90 days of events, so in practice a finding fires when the latest recorded view falls in the 45-to-90-day band. A dashboard abandoned longer than the retention window has no view event left to date it with, and by the fail-closed gate above it abstains too. That known gap on very-long-abandoned dashboards is documented upstream and waits on a longer-retention event source; the rule does not paper over it by guessing.
Finding stale dashboards yourself
aws cloudwatch list-dashboards \ --query 'DashboardEntries[].[DashboardName,LastModified,Size]' --output tableLastModified tracks edits, not views. For actual reads, query CloudTrail for recent
GetDashboard events and see which dashboard names never appear.
Consolidation beats deletion below the free tier
When a finding does fire, deleting the dashboard recovers its full charge. But if you are hovering just above 3 dashboards, merging two related boards into one drops you back into the free tier and achieves the same saving without losing any widgets. Confirm with the owner before removing anything a runbook might still reference.