The problem
RDS cost drift often survives application migrations, environment shutdowns, and traffic collapse because the database is treated as higher risk to touch than surrounding compute. Even when an instance is already stopped, the remaining storage footprint can still reflect stale ownership and retained cost.
Why it happens
- Databases outlive the applications or migrations they were created for.
- Teams keep instances online or retained in stopped form for rollback confidence even after traffic moved elsewhere.
- Database review cycles happen less often than compute cleanup because ownership and data risk are harder to unwind.
What this means for cost
Estimated monthly
$30 to $1,200/mo
Estimated annual
$360 to $14,400/yr
This waste pattern often shows up as $30 to $1,200/mo in recurring monthly cost, or roughly $360 to $14,400/yr if it sits untouched for a year.
How to detect idle RDS instance cost
The best signals are very low CPU, almost no database connections, or a stopped RDS instance that still needs an ownership decision.
Cloud Waste Hunter looks at two metrics over the last 14 days for each RDS instance:
- average
CPUUtilization - peak
DatabaseConnections
If CPU stays at or below 1% and peak connections stay at or below one connection, the instance is flagged for review. Running instances younger than 14 days are excluded until the detector can evaluate a full lookback window. Older running instances are also skipped when CloudWatch does not return enough CPU or connection history to support the full-window claim. The current implementation also flags instances already marked stopped so operators can revisit whether they still need the database footprint at all, and it estimates savings from provisioned database storage rather than from full running-instance cost.
List the instances:
aws rds describe-db-instances \
--query 'DBInstances[].{Identifier:DBInstanceIdentifier,Engine:Engine,Class:DBInstanceClass,Status:DBInstanceStatus,MultiAZ:MultiAZ}'
Then compare CPU and connection activity:
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name CPUUtilization \
--dimensions Name=DBInstanceIdentifier,Value=app-db \
--start-time 2026-03-09T00:00:00Z \
--end-time 2026-03-23T00:00:00Z \
--period 86400 \
--statistics Average
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name DatabaseConnections \
--dimensions Name=DBInstanceIdentifier,Value=app-db \
--start-time 2026-03-09T00:00:00Z \
--end-time 2026-03-23T00:00:00Z \
--period 86400 \
--statistics Maximum
The strongest candidates are long-lived instances with quiet metrics, weak ownership, and no clear application dependency left.
Important caveats
This detector does not inspect query volume, storage churn, replica usage, or backup retention. A database can be legitimate even with almost no connections if it supports scheduled tasks, internal tools, or standby operations.
It also refuses to treat missing CloudWatch CPU or connection telemetry as proof of idleness. When the detector cannot retrieve enough history for an older running instance, it skips that database instead of producing a false idle signal.
For already stopped instances, the displayed savings estimate covers provisioned database storage only. Backup storage, provisioned IOPS, and other retained costs can still remain outside that number.
If the database belongs to an old environment, Idle Load Balancers and Unassociated Elastic IPs are good follow-on reviews because stale application stacks often leave front-end network resources behind alongside the database footprint.
How to fix idle RDS instance cost
A safe database cleanup sequence is:
- Confirm current application ownership and recovery expectations.
- Snapshot or verify the latest backup state if deletion is on the table.
- Stop or downsize the instance first when you want a lower-risk validation step.
aws rds stop-db-instance --db-instance-identifier app-db
aws rds modify-db-instance \
--db-instance-identifier app-db \
--db-instance-class db.t3.micro \
--apply-immediately
How Cloud Waste Hunter helps
Cloud Waste Hunter can translate quiet RDS metrics into a clearer review queue with engine, status, Multi-AZ context, estimated savings, and enough evidence to decide whether the database should stay, shrink, pause, or retire. For related infrastructure cleanup, review the AWS Idle and Underused Resources guide.
FAQ
Why does the detector include stopped RDS instances?
Because a stopped instance is still a strong signal that ownership and retention should be reviewed. It can indicate stale database footprint even if instance-hours are not actively accruing.
Can a low-traffic database still be valid?
Yes. Internal admin systems, scheduled jobs, and standby environments can all have quiet CPU and connection profiles while still being intentional.
Should the fix be stop, downsize, or delete?
It depends on the workload. Temporary environments often only need a stop decision, while long-lived low-utilization databases are stronger candidates for downsizing or retirement.