Skip to content

Blog · Cloud Cost · Published 28 October 2026

Your AWS Bill Was $100. Now It's $500. Here's Where the Money Went.

Nobody decided to spend five times more. The bill grew one default, one forgotten resource and one end-of-support date at a time.

About the numbers. Every price in this post comes from an official AWS page (aws.amazon.com, docs.aws.amazon.com or AWS re:Post), linked under each section, with the region it applies to. AWS prices vary by region and change over time — check the linked page for your region before acting. The $100 → $500 breakdown below is an illustrative example built from those rates, not a client's bill.

How $100 becomes $500

Picture a small product that launched on about $100 a month. Two years later the application hasn't changed much, but these line items have quietly appeared:

What crept inCalculation (official rate)Per month
RDS for PostgreSQL 12, Multi-AZ, 2 vCPU, now in Extended Support (years 1–2)2 vCPU × 2 instances × $0.100/vCPU-hr × 730 h (US East, Ohio)$292.00
8 public IPv4 addresses across instances, load balancers and spare Elastic IPs8 × $0.005/IP-hr × 730 h$29.20
A NAT Gateway in a forgotten dev VPC, processing 300 GB$0.045/hr × 730 h + 300 GB × $0.045/GB (US East, Ohio)$46.35
400 GiB of unattached gp2 volumes from old instances400 × $0.10/GiB-month (US East, N. Virginia)$40.00
CloudWatch Logs: 40 GB/month ingested, 500 GB stored and never expiring40 × $0.50/GB + 500 × $0.03/GB-month (US East, N. Virginia)$35.00
Added on top of the original ~$100$442.55

About $540 a month — and none of it makes the product faster, safer or better. The single biggest line is a database nobody upgraded. From year three of Extended Support that line doubles, to $0.200 per vCPU-hour.

1. Extended Support: the bill for not upgrading

Amazon RDS (MySQL, PostgreSQL) and Aurora

When a major engine version reaches the end of standard support, RDS doesn't force an upgrade — it enrolls the instance in Extended Support by default and starts charging. Per AWS, charges begin “the day after the RDS end of standard support date”, apply to Multi-AZ standby instances too, and stop only when you upgrade or delete the instance.

  • Price (US East, Ohio, per AWS's MySQL 5.7 and PostgreSQL 12 examples): $0.100 per vCPU-hour in years 1–2, $0.200 per vCPU-hour from year 3. Aurora provisioned instances are also charged per vCPU-hour.
  • It's on top of the normal instance price. A 2-vCPU Multi-AZ database adds $292/month in years 1–2.
  • The control: the EngineLifecycleSupport setting defaults to open-source-rds-extended-support. With open-source-rds-extended-support-disabled on new instances, creating one on a version already past end of standard support fails instead of silently billing.

Fix: plan the major-version upgrade before the standard support date, not after. RDS Blue/Green Deployments let you test the new version on a copy and switch over with minimal downtime.

Sources: RDS Extended Support charges (AWS docs) · RDS for PostgreSQL pricing · RDS for MySQL pricing

Amazon EKS

The same pattern applies to Kubernetes. A cluster costs $0.10 per hour in standard support and $0.60 per hour in extended support — six times more, about $73 vs $438 per cluster per month. Standard support lasts 14 months per Kubernetes version, followed by 12 months of extended support. The cluster upgrade policy defaults to EXTENDED; set it to STANDARD if you would rather be auto-upgraded at the end of standard support than charged.

Sources: EKS extended support pricing (AWS Containers blog) · EKS cluster upgrade policy (AWS docs)

2. Public IPv4 addresses

Since 1 February 2024, AWS charges $0.005 per IP per hour for all public IPv4 addresses, whether attached to a service or not — about $3.65 per address per month. Small individually; it adds up across instances, load balancers, NAT Gateways and Elastic IPs nobody released. AWS's Public IP Insights shows where they are.

Fix: release unused Elastic IPs, move instances that don't need inbound internet traffic to private subnets, and front services with one load balancer instead of a public IP each.

Source: Public IPv4 address charge + Public IP Insights (AWS News blog)

3. NAT Gateways

In AWS's US East (Ohio) pricing example, a NAT Gateway costs $0.045 per hour (about $33 a month just to exist) plus $0.045 per GB processed. Two patterns inflate it: one NAT per Availability Zone in non-production environments that don't need that resilience, and heavy traffic to AWS services such as S3 routed through the NAT.

Fix: use gateway VPC endpoints for S3 and DynamoDB so that traffic doesn't go through the NAT, share one NAT in dev/test, and delete NAT Gateways in VPCs nobody uses.

Source: Amazon VPC pricing

4. Unused and outdated storage

  • Unattached EBS volumes — in AWS's words, “These orphaned EBS volumes accrue charges while unattached.”
  • Old snapshots continue to incur storage charges after the original volumes and instances are terminated.
  • gp2 instead of gp3 — in US East (N. Virginia), gp3 is $0.08/GiB-month (with 3,000 IOPS and 125 MiB/s included) versus $0.10 for gp2. AWS: “You can save up to 20% per GiB with gp3 volumes compared to gp2.”
  • Incomplete S3 multipart uploads — S3 keeps charging for uploaded parts until the upload is completed or aborted. A lifecycle rule with AbortIncompleteMultipartUpload cleans them up automatically.

Sources: Deleting unused EBS volumes (AWS blog) · Charges after terminating instances (AWS re:Post) · Optimize EBS volumes (AWS re:Post) · gp2 vs gp3 pricing (AWS docs) · S3 lifecycle examples (AWS docs)

5. Logs that never expire

By default, CloudWatch Logs “stores logs indefinitely and never expire”. In US East (N. Virginia), Standard-class ingestion is $0.50 per GB, and AWS's pricing examples use $0.03 per GB-month for stored logs. Debug logging left on in production drives ingestion; the storage line then grows every month.

Fix: set a retention period on every log group (1 day to 10 years), turn off debug logging in production, and set retention in your Terraform module defaults so new log groups never start at “forever”.

Sources: Amazon CloudWatch pricing · CloudWatch Logs retention (AWS re:Post)

Find all of this in 15 minutes

Read-only commands — run them in every region and account you use:

# Unattached EBS volumes
aws ec2 describe-volumes --filters Name=status,Values=available \
  --query 'Volumes[].{ID:VolumeId,GiB:Size,Type:VolumeType}' --output table

# Elastic IPs not associated with anything
aws ec2 describe-addresses --query 'Addresses[?AssociationId==null].PublicIp'

# RDS engine versions and Extended Support enrollment
aws rds describe-db-instances --query \
  'DBInstances[].[DBInstanceIdentifier,Engine,EngineVersion,EngineLifecycleSupport]' --output table

# EKS cluster versions and support policy
for c in $(aws eks list-clusters --query 'clusters[]' --output text); do
  aws eks describe-cluster --name "$c" \
    --query 'cluster.[name,version,upgradePolicy.supportType]' --output text
done

# Log groups with no retention (= never expire)
aws logs describe-log-groups --query 'logGroups[?!retentionInDays].logGroupName'

# gp2 volumes that could move to gp3
aws ec2 describe-volumes --filters Name=volume-type,Values=gp2 \
  --query 'Volumes[].{ID:VolumeId,GiB:Size}' --output table

Free AWS tools worth turning on today

  • AWS Budgets — monitoring and notifications are free; the first two action-enabled budgets are free too.
  • Cost Anomaly Detection — free, and catches a sudden spike before the invoice does.
  • AWS Compute Optimizer — no additional charge for its right-sizing recommendations.
  • Cost Explorer — free in the console; API requests cost $0.01 each.

Sources: AWS Budgets pricing · Cost Anomaly Detection (AWS blog) · Compute Optimizer pricing · Cost Explorer pricing

Why this keeps happening

None of these are mistakes in the usual sense. They are defaults (Extended Support on, logs kept forever), leftovers (volumes, IPs and NAT Gateways from experiments), and deferred upgrades that AWS now prices explicitly. A one-off clean-up helps for a quarter. What keeps the bill down is putting the fixes where new resources come from: Terraform module defaults, tagging that traces every dollar to an owner, budgets that alert the right team, and an upgrade calendar that runs ahead of support dates.

The short version

Your bill grew because of what nobody turned off, upgraded or put a limit on — not because your product grew. Check Extended Support first (it is usually the biggest line), then public IPv4, NAT Gateways, unattached volumes and log retention. Then move the fixes into your infrastructure code so they stay fixed.

Get an AWS cost review with a written report

This is the work I do: review your AWS accounts and hand you a report that shows

  • where every dollar goes, by service, environment and owner
  • each source of waste, with its monthly cost and the risk of fixing it
  • a prioritised remediation plan: zero-risk quick wins first, then right-sizing and upgrades
  • the fixes built into Terraform defaults, so the savings don't erode next quarter

See the method in practice: cutting AWS bills 20–40% across 10+ client accounts without downtime.