Cloud Cost Checkup — Acme Analytics (fictional)
AWS account 123456789012 · data collected 2026-10-04
Summary
- Last full month (2026-09): $11,124
- Identified savings: $2,835/month (~$34,024/year), about 25% of the bill
- 21 findings, sorted by estimated saving. Quick wins (low effort, high confidence): $1,193/month.
| # | Finding | Est. monthly saving | Confidence | Effort |
|---|---|---|---|---|
| 1 | Upgrade databases out of RDS Extended Support | $584 | high | high |
| 2 | Buy a 1-year Compute Savings Plan | $566 | high | low |
| 3 | Delete unattached EBS volumes | $335 | high | low |
| 4 | Expire 30 EBS snapshots older than 90 days | $231 | low | low |
| 5 | Reserve steady RDS instances | $228 | high | low |
| 6 | Move databases to newer, cheaper instance classes | $166 | high | medium |
| 7 | Turn off Multi-AZ on non-production databases | $128 | medium | low |
| 8 | Route S3/DynamoDB traffic around the NAT gateway | $126 | low | low |
| 9 | Stop or remove idle EC2 instances | $67.74 | medium | low |
| 10 | Downsize lightly used databases | $63.87 | medium | medium |
| 11 | Move to newer, cheaper instance families | $57.82 | high | medium |
| 12 | Consider Graviton (ARM) instances | $55.70 | medium | high |
| 13 | Shut down databases nobody connects to | $49.64 | medium | low |
| 14 | Delete idle load balancers | $49.28 | high | low |
| 15 | Downsize over-provisioned EC2 instances | $36.50 | medium | medium |
| 16 | Run Lambda functions on ARM (Graviton) | $28.00 | medium | medium |
| 17 | Add lifecycle rules / Intelligent-Tiering to large S3 buckets | $19.32 | low | low |
| 18 | Set retention on CloudWatch log groups | $19.11 | medium | low |
| 19 | Convert 4 gp2 volumes to gp3 | $11.00 | high | low |
| 20 | Clean up long-stopped instances | $10.00 | medium | low |
| 21 | Release unattached Elastic IPs | $3.65 | high | low |
Savings from different findings can overlap: buy commitments (Savings Plans, reservations) only after rightsizing and cleanup, or you'll commit to waste.
1. Upgrade databases out of RDS Extended Support
Estimated saving: $584/month · confidence high · effort high
These databases run a major engine version past the end of AWS's standard support, or will within six months of 2026-10-04. AWS then charges RDS Extended Support per vCPU per hour on top of the instance price, and for most versions the rate rises in year 3. Upgrading to a version in standard support (or deleting the database) stops the charge. The saving counts only charges already being billed; upcoming ones are listed with their cost from the start date.
- billing-db (db.m5.large, PostgreSQL 12.22, Multi-AZ, us-east-1): charged for Extended Support since 2025-03-01. 2 vCPUs × 2 (the Multi-AZ standby is charged too) × $0.100/vCPU-hr × 730 = $292/mo. Rises to $0.200/vCPU-hr ($584/mo) on 2027-03-01. Upgrade to PostgreSQL 17 or 18.
- app-pg14 (db.r6g.large, PostgreSQL 14.18, us-east-1): Extended Support charges start 2027-03-01. AWS hasn't published a rate for this version in us-east-1 yet, so there's no estimate. Upgrade to PostgreSQL 17 or 18 before then.
- orders-aurora-1 (db.r5.large, Aurora MySQL 5.7.mysql_aurora.2.11.2, cluster orders-aurora, us-east-1): charged for Extended Support since 2024-12-01. 2 vCPUs × $0.100/vCPU-hr × 730 = $146/mo. AWS's calendar starts year-3 pricing on 2026-12-01, but AWS hasn't published a year-3 rate for us-east-1. Upgrade to Aurora MySQL version 3.
- orders-aurora-2 (db.r5.large, Aurora MySQL 5.7.mysql_aurora.2.11.2, cluster orders-aurora, us-east-1): charged for Extended Support since 2024-12-01. 2 vCPUs × $0.100/vCPU-hr × 730 = $146/mo. AWS's calendar starts year-3 pricing on 2026-12-01, but AWS hasn't published a year-3 rate for us-east-1. Upgrade to Aurora MySQL version 3.
- events-serverless (db.serverless, Aurora PostgreSQL 13.9, cluster events, us-east-1): charged for Extended Support since 2026-03-01. Aurora Serverless v2 is billed per ACU-hour, and the bundle has no ACU usage, so there's no estimate. The rate rises on 2028-03-01. Upgrade to Aurora PostgreSQL 17 or 18.
How:
- List the major versions you can upgrade to directly:
aws rds describe-db-engine-versions --engine ENGINE --engine-version VERSION --query "DBEngineVersions[*].ValidUpgradeTarget[*].{EngineVersion:EngineVersion}" --output text - Test the upgrade on a copy first (restore a snapshot, or create an RDS Blue/Green Deployment). Major versions can change query behavior, and extensions and custom parameter groups may need updating.
- RDS for PostgreSQL and MySQL: Modify > DB engine version. Aurora: modify the cluster with
--engine-version ... --allow-major-version-upgrade. Take a snapshot first. An in-place major upgrade makes the database unavailable while it runs; a Blue/Green switchover shortens the outage but doesn't remove it. - For new databases on old versions, set
--engine-lifecycle-support open-source-rds-extended-support-disabledso they can't enroll silently. Setting it on a database already past standard support upgrades that database automatically.
Watch out: Major version upgrades can break queries, extensions and drivers. Test before production.
2. Buy a 1-year Compute Savings Plan
Estimated saving: $566/month · confidence high · effort low
AWS's own analysis of your last 30 days of usage recommends a Compute Savings Plan with an hourly commitment of $3.10/hr (1-year, no upfront). Estimated saving: 22% on covered compute. AWS estimates $612/mo at today's usage; the figure here is reduced to reflect the compute removed by the rightsizing findings above.
How:
- Do the rightsizing and cleanup findings first, so you don't commit to waste.
- Then re-check the recommendation: AWS Console > Billing and Cost Management > Savings Plans > Recommendations.
- Buy a commitment at or slightly below the recommended hourly amount. Compute Savings Plans apply to EC2, Fargate and Lambda across regions and instance families.
Watch out: A 1-year commitment. If usage drops below the commitment, you still pay for it. Committing ~80% of the recommendation keeps headroom.
3. Delete unattached EBS volumes
Estimated saving: $335/month · confidence high · effort low
These disks aren't attached to any instance, but are billed every month.
- vol-0orphan1 db-migration-scratch (500 GB gp2, us-east-1, created 400 days ago): $50.00/mo
- vol-0orphan2 (200 GB io1, us-east-1, created 120 days ago): $285/mo
How:
- Snapshot each volume first if there's any doubt (a snapshot costs less than the volume).
- Then delete it:
aws ec2 delete-volume --volume-id vol-... --region ...
4. Expire 30 EBS snapshots older than 90 days
Estimated saving: $231/month · confidence low · effort low
Snapshots cost $310 last month. 30 snapshots are over 90 days old and not used by any AMI. Snapshots are incremental, so deleting one frees only blocks no other snapshot uses: the saving is an estimate.
- snap-0039 (100 GB source volume, 390 days old, us-east-1) nightly
- snap-0038 (100 GB source volume, 380 days old, us-east-1) nightly
- snap-0037 (100 GB source volume, 370 days old, us-east-1) nightly
- snap-0036 (100 GB source volume, 360 days old, us-east-1) nightly
- snap-0035 (100 GB source volume, 350 days old, us-east-1) nightly
- snap-0034 (100 GB source volume, 340 days old, us-east-1) nightly
- snap-0033 (100 GB source volume, 330 days old, us-east-1) nightly
- snap-0032 (100 GB source volume, 320 days old, us-east-1) nightly
- snap-0031 (100 GB source volume, 310 days old, us-east-1) nightly
- snap-0030 (100 GB source volume, 300 days old, us-east-1) nightly
- snap-0029 (100 GB source volume, 290 days old, us-east-1) nightly
- snap-0028 (100 GB source volume, 280 days old, us-east-1) nightly
- snap-0027 (100 GB source volume, 270 days old, us-east-1) nightly
- snap-0026 (100 GB source volume, 260 days old, us-east-1) nightly
- snap-0025 (100 GB source volume, 250 days old, us-east-1) nightly
- snap-0024 (100 GB source volume, 240 days old, us-east-1) nightly
- snap-0023 (100 GB source volume, 230 days old, us-east-1) nightly
- snap-0022 (100 GB source volume, 220 days old, us-east-1) nightly
- snap-0021 (100 GB source volume, 210 days old, us-east-1) nightly
- snap-0020 (100 GB source volume, 200 days old, us-east-1) nightly
- ...and 10 more
How:
- Keep what your backup policy requires; delete the rest.
- Going forward, let Amazon Data Lifecycle Manager or AWS Backup expire snapshots automatically.
- For snapshots you must keep for years, use the EBS Snapshots Archive tier (75% cheaper).
5. Reserve steady RDS instances
Estimated saving: $228/month · confidence high · effort low
AWS recommends reserved instances for RDS databases that have run steadily for the last 30 days. This is AWS's own estimate for today's databases: if you act on the database findings above, it can overlap them, so re-check it afterwards.
- 1 × db.r6g.xlarge PostgreSQL (Multi-AZ, US East (N. Virginia)): saves $228/mo
How:
- Confirm each database will run for at least a year at this size.
- AWS Console > RDS > Reserved instances > Purchase. Match engine, class, region and Multi-AZ exactly.
Watch out: 1-year commitment tied to engine, class family and region.
6. Move databases to newer, cheaper instance classes
Estimated saving: $166/month · confidence high · effort medium
Same size, lower price. Graviton (g) classes are cheapest and work with MySQL, PostgreSQL, MariaDB and Aurora.
- prod-db (db.r5.xlarge, postgres, Multi-AZ, us-east-1) → db.r6g family: saves $73.00/mo
- staging-db (db.m4.large, mysql, Multi-AZ, us-east-1) → db.m6g family: saves $8.39/mo (previous generation)
- billing-db (db.m5.large, postgres, Multi-AZ, us-east-1) → db.m6g family: saves $27.74/mo
- orders-aurora-1 (db.r5.large, aurora-mysql, us-east-1) → db.r6g family: saves $28.47/mo
- orders-aurora-2 (db.r5.large, aurora-mysql, us-east-1) → db.r6g family: saves $28.47/mo
How:
- Modify the DB instance class during a maintenance window.
Watch out: Brief interruption (a failover on Multi-AZ).
7. Turn off Multi-AZ on non-production databases
Estimated saving: $128/month · confidence medium · effort low
Multi-AZ doubles the price for a standby. Development and test databases rarely need it. Names were matched by pattern: confirm these really are non-production.
- staging-db (db.m4.large, mysql, Multi-AZ, us-east-1): looks non-production — single-AZ saves $128/mo
How:
- Modify the instance and set Multi-AZ to No.
8. Route S3/DynamoDB traffic around the NAT gateway
Estimated saving: $126/month · confidence low · effort low
NAT gateways cost $98.50 in hourly charges and $420 in data processing last month (3 gateway(s)). Traffic to S3 and DynamoDB through a NAT is billed at $0.045/GB; through a gateway VPC endpoint it's free. The estimate assumes 30% of NAT traffic is S3/DynamoDB. VPC Flow Logs would give the real share.
- vpc-dev (us-east-1): no gateway endpoint for dynamodb, s3
- vpc-prod (us-east-1): no gateway endpoint for dynamodb
How:
- Create gateway endpoints (free) for S3 and DynamoDB in each VPC and add them to private route tables.
- If several NAT gateways serve non-production VPCs, one per VPC (not per AZ) is usually enough there.
9. Stop or remove idle EC2 instances
Estimated saving: $67.74/month · confidence medium · effort low
These instances barely used any CPU in the last 14 days. They may be forgotten test boxes, or low-traffic services that could share a host. Confirm with the owner before stopping.
- i-0idle old-vpn (t2.large, us-east-1): 14-day avg CPU 0.6%, peak 3.1% — $67.74/mo
How:
- Ask the owner what each instance does. Check the Name tag, security groups and recent logins.
- If unneeded: create an AMI or snapshot, then stop. Terminate after a quiet week.
- If needed but tiny: move to a t4g/t3 burstable instance, or consolidate.
Watch out: CPU alone doesn't capture memory- or I/O-bound workloads. Check before removing.
10. Downsize lightly used databases
Estimated saving: $63.87/month · confidence medium · effort medium
These databases use little CPU. Check memory (FreeableMemory) and IOPS before resizing.
- staging-db (db.m4.large, mysql, Multi-AZ, us-east-1): avg CPU 4.0%, peak 12.0% — one size down saves ~$63.87/mo
How:
- Modify the DB class during the maintenance window (Multi-AZ makes this a short failover).
Watch out: Database memory matters for caching; watch performance after the change.
11. Move to newer, cheaper instance families
Estimated saving: $57.82/month · confidence high · effort medium
Same size, same CPU architecture, lower price. Newer families are usually also faster. Where an instance is also being downsized, the saving is calculated on the smaller size.
- i-0web1 web-1 (m5.xlarge, us-east-1) → m6a.xlarge: saves $14.02/mo
- i-0web2 web-2 (m5.xlarge, us-east-1) → m6a.xlarge: saves $14.02/mo
- i-0old1 jenkins (m4.large, us-east-1) → m6a.large: saves $4.96/mo (previous-generation type)
- i-0wrk1 worker (c5.2xlarge, us-east-1) → c6a.2xlarge: saves $24.82/mo
How:
- Check the AMI supports the newer family (ENA and NVMe drivers; any AMI from the last few years does).
- Stop → change instance type → start, or update the launch template for Auto Scaling groups.
Watch out: Brief downtime per instance for the stop/start.
12. Consider Graviton (ARM) instances
Estimated saving: $55.70/month · confidence medium · effort high
AWS Graviton instances cost less for the same size and are often faster. Most Linux workloads in interpreted languages, Java, Go, or containers move easily. Savings are on top of the previous finding.
- i-0web1 web-1 (m5.xlarge, us-east-1) → m6g.xlarge (Graviton/ARM): saves a further $13.72/mo
- i-0web2 web-2 (m5.xlarge, us-east-1) → m6g.xlarge (Graviton/ARM): saves a further $13.72/mo
- i-0old1 jenkins (m4.large, us-east-1) → m6g.large (Graviton/ARM): saves a further $3.43/mo
- i-0wrk1 worker (c5.2xlarge, us-east-1) → c6g.2xlarge (Graviton/ARM): saves a further $24.82/mo
How:
- Rebuild the AMI or container image for arm64 (multi-arch Docker builds make this routine).
- Test one instance, then roll out.
Watch out: Native binaries and some commercial software may not have ARM builds.
13. Shut down databases nobody connects to
Estimated saving: $49.64/month · confidence medium · effort low
No connections at all in 14 days.
- reporting-old (db.t3.medium, mysql, us-east-1): zero connections in 14 days — $49.64/mo
How:
- Take a final snapshot, then delete (or stop it: stopped RDS auto-starts after 7 days).
14. Delete idle load balancers
Estimated saving: $49.28/month · confidence high · effort low
Load balancers bill hourly whether or not they serve traffic.
- old-staging-alb (application, us-east-1): no registered targets
- quiet-alb (application, us-east-1): zero requests in 14 days
- legacy-elb (classic, us-east-1): no instances
How:
- Confirm no DNS record points at it, then delete it and its unused target groups.
15. Downsize over-provisioned EC2 instances
Estimated saving: $36.50/month · confidence medium · effort medium
These instances use a small fraction of their CPU. A smaller size in the same family would carry the same load.
- i-0old1 jenkins (m4.large, us-east-1): avg CPU 9.0%, peak 31.0% — one size down saves ~$36.50/mo
How:
- Check memory use too (CloudWatch agent or
free -m): CPU is not the only constraint. - Change type during a maintenance window: stop → Actions > Instance settings > Change instance type → start.
- For Auto Scaling groups, update the launch template instead.
Watch out: Requires a stop/start (brief downtime) unless behind a load balancer with spare capacity.
16. Run Lambda functions on ARM (Graviton)
Estimated saving: $28.00/month · confidence medium · effort medium
x86 Lambda compute cost $140 last month. arm64 is 20% cheaper per GB-second.
- ingest (us-east-1)
How:
- Switch the architecture setting; rebuild any functions with native dependencies for arm64.
17. Add lifecycle rules / Intelligent-Tiering to large S3 buckets
Estimated saving: $19.32/month · confidence low · effort low
Large Standard-class buckets without lifecycle rules usually hold data nobody reads. Intelligent-Tiering moves untouched objects to cheaper tiers automatically. The estimate assumes a 20% overall saving.
- acme-uploads (us-east-1): 4,200 GB in Standard, no lifecycle rules
How:
- Add a lifecycle rule: transition to Intelligent-Tiering after 0–30 days.
- Also expire old object versions and incomplete multipart uploads (often hidden costs).
Watch out: Intelligent-Tiering adds a small per-object monitoring fee; skip buckets of millions of tiny objects.
18. Set retention on CloudWatch log groups
Estimated saving: $19.11/month · confidence medium · effort low
These log groups keep everything forever. The estimate assumes a 30–90 day retention removes about 70% of stored data.
- /aws/lambda/ingest (us-east-1): 850.0 GB stored, never expires
- /var/log/app (us-east-1): 60.0 GB stored, never expires
How:
aws logs put-retention-policy --log-group-name NAME --retention-in-days 30- Export to S3 first if anything must be kept for compliance.
19. Convert 4 gp2 volumes to gp3
Estimated saving: $11.00/month · confidence high · effort low
gp3 is 20% cheaper per GB than gp2 with equal or better baseline performance. 800 GB affected. Savings account for provisioning matching IOPS/throughput on large volumes.
- vol-0web1 (500 GB, us-east-1): saves $5.00/mo
- vol-0web2 (100 GB, us-east-1): saves $2.00/mo
- vol-0old1 (100 GB, us-east-1): saves $2.00/mo
- vol-0wrk1 (100 GB, us-east-1): saves $2.00/mo
How:
- Convert in place with no downtime:
aws ec2 modify-volume --volume-id vol-... --volume-type gp3 - Update launch templates, Terraform/CloudFormation, and EKS StorageClasses so new volumes default to gp3.
20. Clean up long-stopped instances
Estimated saving: $10.00/month · confidence medium · effort low
Stopped instances don't bill for compute, but their disks keep billing.
- i-0stop analytics-poc (r5.large, us-east-1, stopped since 2025-11-02): volumes cost $10.00/mo
How:
- If an instance has been stopped for weeks and nobody misses it: create an AMI, then terminate.
- Delete the AMI later if it's still unused after a quarter.
21. Release unattached Elastic IPs
Estimated saving: $3.65/month · confidence high · effort low
Each idle Elastic IP bills $0.005/hr.
- 3.3.3.3 (us-east-1)
How:
- Release with
aws ec2 release-address --allocation-id eipalloc-... --region ... - Check DNS records and allow-lists first, in case something points at the address.
Other observations
- CloudWatch Logs ingestion cost $300 last month. Ingestion is usually the bigger log cost: lowering log levels in chatty services, or using the Infrequent Access log class, reduces it.
- Spend grew 25% month over month ($8,899 → $11,124).
- Internet data transfer out cost $95.00 last month. Serving static or cacheable content through CloudFront is often cheaper (1 TB/month free) and faster.
- AWS Compute Optimizer isn't enabled. It's free, and gives memory-aware rightsizing advice that sharpens future checkups: Console > Compute Optimizer > Get started.
- Cost Explorer's EC2 rightsizing recommendations are turned off. They're free to enable: Billing and Cost Management > Cost Explorer > Preferences (in the payer account).
- 1 collector calls were denied (missing permissions), so these areas weren't checked: regions/us-east-1/rds_clusters
Appendix: spend by service
| Service | 2026-04 | 2026-05 | 2026-06 | 2026-07 | 2026-08 | 2026-09 |
|---|---|---|---|---|---|---|
| Amazon Elastic Compute Cloud - Compute | $2,720 | $2,856 | $2,992 | $3,128 | $3,264 | $4,080 |
| Amazon Relational Database Service | $1,680 | $1,764 | $1,848 | $1,932 | $2,016 | $2,520 |
| EC2 - Other | $1,160 | $1,218 | $1,276 | $1,334 | $1,392 | $1,740 |
| Amazon Simple Storage Service | $496 | $521 | $546 | $570 | $595 | $744 |
| AWS Support (Business) | $488 | $512 | $537 | $561 | $586 | $732 |
| AmazonCloudWatch | $432 | $454 | $475 | $497 | $518 | $648 |
| Amazon Elastic Load Balancing | $168 | $176 | $185 | $193 | $202 | $252 |
| Amazon Virtual Private Cloud | $144 | $151 | $158 | $166 | $173 | $216 |
| AWS Lambda | $128 | $134 | $141 | $147 | $154 | $192 |
| Tax | $0.00 | $0.00 | $0.00 | $0.00 | $0.00 | $0.00 |
| Total | $7,416 | $7,787 | $8,158 | $8,528 | $8,899 | $11,124 |
Method and limits
Built from read-only data: Cost Explorer, resource metadata and 14 days of CloudWatch metrics. Prices are AWS on-demand list prices; your negotiated discounts, credits or existing commitments may change the numbers. Utilization-based findings need a quick check with whoever owns the resource. Nothing in your account was changed.