Monthly CloudWatch cleanup audit for waste and dead alarms
On the first Monday of every month, find the alarms nobody watches and the monitoring you quietly pay for, then get a costed cleanup list in Slack and Linear.
On the first Monday of every month at 9am, audit my Amazon CloudWatch setup for waste and quiet misconfiguration, then report what should be cleaned up. This workflow must only ever read and recommend. It must never delete, disable, mute, or edit an alarm, dashboard, or metric on its own. A quiet alarm is sometimes deliberate, and a human needs to make that call, so every finding is a recommendation for a person to approve.
Start with Describe Alarms to pull every alarm in the account, paging through until there are no more results, and include both metric alarms and composite alarms. From that full list, flag the two silent failure modes. First, alarms parked in INSUFFICIENT_DATA, which usually means the resource behind them was deleted, renamed, or stopped reporting, so the alarm looks healthy but is watching nothing. Second, alarms with no actions attached, meaning nobody is ever told when they fire. Treat an alarm as unactioned if its alarm, OK, and insufficient-data action lists are all empty, and separately call out alarms that do have actions configured but have actions disabled, since those are silently inert too.
Then use Describe Alarm History across the last 90 days to sort the rest into dead weight and noise. Dead weight is alarms that never changed state at all in that window, which are candidates for removal or for a threshold that would actually trip. Noise is alarms that changed state more than 20 times, which have almost certainly been tuned out by the team and need their thresholds revisited rather than deleted. Make the 20 state-change threshold an editable value near the top of the workflow. If the account has a large number of alarms, prioritize history lookups over alarms that are not already flagged as unactioned or stuck, so the run stays within a sensible number of calls, and note in the report if any alarms were not fully checked.
Next use List Dashboards to count how many dashboards exist and compare that against the three that AWS includes at no cost, so anything beyond three is billable. Then use List Metrics filtered to my non-AWS namespaces, meaning any namespace that does not begin with the AWS prefix, to count custom metrics, which bill per metric per month. Skip the standard AWS service namespaces, since those are not what drives custom metric charges.
Do not attempt to audit log groups, log retention, or log ingestion volume. This connection covers metrics, alarms, and dashboards only, and logs live behind a separate service, so leave logs out of the report entirely rather than guessing at them.
Group everything into a prioritized cleanup list with a rough monthly dollar estimate per category. Use these as editable default rates and state the assumptions in the report: custom metrics at 0.30 US dollars per metric per month for the first 10,000, dashboards at 3 US dollars per dashboard per month beyond the three free ones, and an editable default for the per alarm monthly price with standard resolution alarms commonly published at around 0.10 US dollars. Present the total as an approximate figure, never as an exact invoice number, and say plainly that AWS pricing varies by region and changes over time. Rank the categories by a combination of dollars recoverable and risk, and put unactioned or stuck alarms high in the list even where the dollar value is small, because those represent real monitoring blind spots rather than just cost.
Post the summary to my Slack ops channel with Send a Message. Keep it skimmable: a one-line headline with the approximate monthly total and the number of items found, then the prioritized categories with a count and a rough cost each, then the single most important thing to fix first. Do not paste the entire itemized list into Slack, and link to the Linear issue for the detail.
Then open a single Linear issue with Create Issue holding the itemized checklist, so the cleanup actually gets an owner. One issue per run, not one per finding. Title it with the month and the approximate recoverable amount, and write the description in Markdown as checkbox items grouped by the same categories used in the Slack summary, naming each specific alarm, dashboard, or metric so someone can work through it directly. Include the pricing assumptions used and a short note that every item needs human review before anything is removed.
Note in both outputs that this audit covers only the region the CloudWatch connection is configured for, since monitoring data is region scoped and never cross region, and that teams running several regions can duplicate this workflow once per region.
What does this prompt do?
- Reviews every alarm in your account and flags two quiet failure modes: alarms sitting with no data coming in, which usually means the resource behind them was renamed or deleted, and alarms with nobody attached to them, which means they fire into thin air and no one is ever told.
- Looks back over 90 days to separate dead weight from noise. Dead weight is alarms that have never once changed state. Noise is alarms that have flipped back and forth so many times the team has learned to tune them out.
- Counts your dashboards and your custom metrics, the two parts of monitoring that quietly add to the monthly bill, and puts a rough dollar figure next to each category so you can see what the mess is costing.
- Posts a prioritized summary to your Slack ops channel and opens a single Linear issue holding the itemized checklist, so the cleanup gets a real owner instead of being a screenshot someone forgets.
What do I need to use this?
- An Amazon Web Services account with monitoring set up, connected for the region you want reviewed
- A Slack workspace and the ops channel where the monthly summary should land
- A Linear account and the team that should own the cleanup work
- Nothing gets changed in AWS, so read-only access is enough
How can I customize it?
- Change the timing. First Monday at 9am matches how most teams review cloud spend, but any monthly or quarterly cadence works just as well.
- Adjust what counts as noisy. The default flags anything that changed state more than 20 times in 90 days, which you can raise for busy production accounts or lower for quiet ones.
- Edit the pricing assumptions. The dollar estimates use published list prices as starting defaults, and you can swap in the rates that match your region and agreement.
- Point the outputs somewhere else, such as a different Slack channel per team, or a specific Linear project for infrastructure work.
FAQs
Will this delete or switch off any of my alarms?
Does it cover all of my AWS regions at once?
How accurate is the monthly dollar estimate?
What makes an alarm count as noisy rather than useful?
Do I need to be an engineer to make sense of the report?
Related templates
When someone leaves, we check which shared passwords they used in their final months and post a ranked rotation list to your security channel.
Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.
Twice every weekday, the conversations from your social inbox land on the right HubSpot contact timelines, with a Slack recap for sales.
Every morning, find the addresses that hard bounced or filed a spam complaint, update the matching HubSpot contacts, and post a short Slack recap.
Every weekday at 4pm, spot the threads that went quiet, stage a ready-to-send nudge in your mailbox, and get a ranked Slack recap.
When you merge a fix in GitHub, this agent checks the matching dead-letter queue, replays the failed messages, and reports back on the pull request and in Slack.
Stop paying for monitoring nobody reads.
Get a costed, prioritized cleanup list in your ops channel on the first Monday of every month, with a Linear issue attached so it actually gets done.