Cloud Databases

AWS Database Cost Management: Reserved Instances, Idle DB Shutdown, and Storage

Cut AWS database costs systematically: find over-provisioned RDS with Compute Optimizer, stop dev DBs after hours, buy Reserved Instances, and control storage growth.

JusDB Team
November 3, 2025
Updated May 12, 2026
5 min read
176 views

Database costs are often the second-largest AWS bill item after compute. Here is a systematic approach to identifying and eliminating waste.

Top Cost Drivers

  • Over-provisioned instances: most common, easiest to fix
  • Multi-AZ on non-production: doubles cost unnecessarily
  • Storage auto-scaling: grows but never shrinks
  • On-demand instead of Reserved: 40-60% premium vs 1-year RI
  • Idle instances: dev/test DBs running 24/7

Find Over-Provisioned Instances

bash
# List all RDS instances with CPU metrics
aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name CPUUtilization \
  --dimensions Name=DBInstanceIdentifier,Value=my-db \
  --start-time 2025-10-01T00:00:00Z \
  --end-time 2025-10-15T00:00:00Z \
  --period 86400 \
  --statistics Average,Maximum
bash
# Use AWS Compute Optimizer for RDS recommendations
aws compute-optimizer get-rds-database-recommendations \
  --region us-east-1 \
  --filters Name=finding,Values=Overprovisioned

Stop Dev/Test Instances After Hours

bash
# Lambda + EventBridge: stop RDS at 7pm, start at 8am weekdays
aws events put-rule \
  --name stop-dev-db \
  --schedule-expression 'cron(0 19 ? * MON-FRI *)' \
  --state ENABLED

# Lambda function
import boto3
def handler(event, context):
    rds = boto3.client('rds')
    rds.stop_db_instance(DBInstanceIdentifier='dev-postgres')

Purchase Reserved Instances

text
Instance: db.r6g.large in us-east-1
On-Demand:   $0.24/hour  = $2,102/year
1-year RI:   $0.151/hour = $1,323/year  (37% savings)
3-year RI:   $0.103/hour = $902/year    (57% savings)

Storage Reclamation

sql
-- PostgreSQL: find tables that could be shrunk
SELECT tablename,
       pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size,
       n_dead_tup,
       last_vacuum
FROM pg_stat_user_tables
WHERE n_dead_tup > 100000
ORDER BY n_dead_tup DESC;

-- After VACUUM FULL or pg_repack, storage cannot be reclaimed in RDS
-- without a snapshot restore to a smaller storage allocation.
-- Consider using pg_repack to reclaim pages for reuse instead.

Key Takeaways

  • Use AWS Compute Optimizer to find over-provisioned RDS instances automatically
  • Stop dev/test databases after hours — 12 hours/day × 5 days saves 65% vs 24/7
  • Buy 1-year Reserved Instances for any DB running stably for more than 6 months
  • Disable Multi-AZ on non-production environments to halve those instance costs

JusDB Can Help

JusDB AWS cost optimization audits typically find 30-50% savings in database spending. Contact us for a free cost review.

Share this article

JusDB Team

Official JusDB content team