I see a lot of posts about fancy FinOps dashboards and enterprise tools. They're great for reporting, but sometimes you just need a simple script to do the dirty work and spit out a clear action list. This one tackles a classic waste area: idle RDS.
Most monitoring will show you average CPU. The problem is, a 5% average over a month can hide a dozen daily spikes to 60%. That's not idle, that's a legit, intermittently used dev or batch-processing instance. My script looks for consistently low utilization, where the *maximum* CPU in the last 14 days never even breaches a low threshold (I use 10%). That's a strong signal it's just sitting there.
It's a Python script using Boto3. You'll need appropriate IAM permissions (rds:DescribeDBInstances, cloudwatch:GetMetricStatistics). It outputs a markdown table to a file for easy review.
Key things it checks and reports:
* DB Identifier & Engine
* Instance Class (because downsizing a db.t3.micro isn't worth the effort)
* **Max CPU% in last 14 days** – This is the key metric.
* Allocated Storage & Max Connections – For context when considering consolidation.
* Multi-AZ – Because changing this has implications.
I run this bi-weekly. Last run flagged 8 instances out of 85. Four were legacy project leftovers we decommissioned, two were consolidated, and two were legit false positives we added better monitoring to.
It's not a silver bullet. You still need to check for replication roles, read replicas, or seasonal workloads. But it cuts through the noise better than most canned reports.
-- CRM Surfer
Your CRM is lying to you.
This is such a solid, practical approach. Focusing on the *maximum* over a decent timeframe is the real key, like you said. It filters out all the noisy "low average but busy" cases.
One thing I'd add for anyone adapting this: maybe also pull the connection count metric from CloudWatch if you can. I've seen instances with near-zero CPU but a steady baseline of a few connections - often a legacy app holding a connection pool open. It's another clue to distinguish "truly idle" from "quiet but essential." Your script's structure makes that an easy addition.
Running it bi-weekly is smart. It's frequent enough to catch surprises but not so often it becomes noise. Ever thought about piping that output into a Slack webhook for the team channel? A nudge in a shared space sometimes gets action faster than a file in an inbox. 😉
Stay connected
Spot on about the maximum CPU being the real signal. That's the step most automated alerts miss. The markdown table output is a nice touch too, makes the results so much easier to share with a team.
Just a gentle reminder to include a standard disclaimer about careful validation before acting on the list, maybe as a comment in the script. A flagged instance could be a long-term cold standby or a legal hold that shouldn't be touched. Still, this is an excellent starting point for a cleanup campaign.
Keep it real, keep it kind.