An AWS bill that climbs while traffic stays flat usually has one of three causes: data nobody deletes keeps piling up, a discount has ended, or a new charge started on a set date. To see why your AWS bill is so high, compare the month before the climb with the latest one in Cost Explorer.
Compare two months in Cost Explorer
Open the free Compare view under Report parameters, pick two of the last 13 months and group by service. According to the cost comparison documentation, Compare shows the three biggest changes and names the reason for each: usage, discounts, or other charges and credits.
Usage rising by a similar amount every month points to data that only grows. If traffic is flat and AWS puts a jump down to discounts or credits, a Savings Plan or reservation has usually expired, or your credits have run out. Then filter to the growing service in the normal Cost Explorer view and group it by Usage type.
The chart for this part is in the original post.
A slow climb usually triggers no alert. According to the Cost Anomaly Detection FAQ, the default setup alerts only when an anomaly exceeds both 40% of expected spend and $100. A budget with a lower threshold warns sooner; see the post on AWS budget alerts.
S3 versions, ECR images and RDS storage
With versioning on, S3 keeps every version of a file as a separate, full object at the normal rate. Deleting a file frees nothing, because S3 only adds a delete marker. Incomplete multipart uploads grow the same way and are billed until someone completes or aborts them. S3 Storage Lens shows both in two free metrics, Noncurrent version bytes and Incomplete multipart upload bytes.
ECR, the container image registry, also fills up when every deploy pushes a new image. A lifecycle policy removes old images by count or age. Check it in the lifecycle policy preview first, as AWS advises, and keep enough recent images to roll back.
On RDS the disk grows. With storage autoscaling on, AWS enlarges it by itself when space runs low but never shrinks it, so you keep paying for the added gigabytes after the data is deleted. Manual RDS snapshots ignore the retention period and stay until you delete them.
CloudWatch logs never expire by default. I cover them, and EBS snapshots left behind by old scripts, in what I check in an AWS cost audit.
A lifecycle rule for S3
The rule below covers the whole bucket: it deletes versions that have been noncurrent for 30 days and aborts uploads older than 7 days. The put command replaces every existing rule on the bucket, so read the current rules first and copy any you want to keep into the file. If one of them keeps old versions longer than 30 days, leave this rule out: where rules overlap, S3 honours the shorter expiration. The commands are for AWS CLI v2.
aws s3api \ get-bucket-lifecycle-configuration \ --bucket my-bucket Save the rule as lifecycle.json:
{ "Rules": [ { "ID": "cleanup", "Status": "Enabled", "Filter": { "Prefix": "" }, "NoncurrentVersionExpiration": { "NoncurrentDays": 30 }, "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 } } ] } aws s3api \ put-bucket-lifecycle-configuration \ --bucket my-bucket \ --lifecycle-configuration \ file://lifecycle.json Deleted versions cannot be recovered, so if you reach for old files months later, raise NoncurrentDays.
When a Savings Plan or reservation ends
Neither a Savings Plan nor a reservation renews itself. Once an RDS reservation ends, the database is billed at the on-demand rate. Before a Savings Plan ends, you can queue a new plan or click Renew Savings Plan. Turn on the expiry email under Manage alert subscriptions on the Savings Plans page.
Year three of RDS Extended Support
RDS adds an Extended Support charge for MySQL and PostgreSQL versions whose standard support has ended, and doubles it in year three. According to RDS pricing on 11 November 2026, a 2-vCPU database on MySQL 5.7 in Frankfurt (eu-central-1) paid about $178 a month for support alone, and since 1 March 2026 it has paid about $356. A Multi-AZ standby is charged too.
For PostgreSQL 11, year three began on 1 April 2026, and PostgreSQL 12 follows on 1 March 2027. The charge stops after an upgrade to a version with standard support. MySQL 8.0 has been in Extended Support since 1 August 2026, as I covered in the post on the MySQL 8.0 charge.
Old EBS snapshots cost less in the archive
The only snapshot left from a deleted server can go to the EBS snapshot archive. EBS pricing for Frankfurt on 11 November 2026 puts a snapshot holding 500 GB of data at $27 a month in the standard tier and $6.75 in the archive. One restore costs $16.20.
An archived snapshot must stay at least 90 days, or you pay for the remaining days. Restoring it takes up to 72 hours, and only then can you create a volume from it.
Never archive a daily, weekly or monthly snapshot of a disk that is still in use and has newer copies. The archive bills it at full size, while the standard tier barely gets cheaper because the newer copies share most of its blocks, so according to AWS guidelines the total cost usually rises.
What it means for a small team
Once a month, after the invoice arrives, run Compare on the last month and the one six months earlier. This week, check the two S3 metrics above in Storage Lens and add the lifecycle rule wherever they are not zero. Then check which engine versions your RDS databases run, when your Savings Plans and reservations end and whether the expiry emails are on.
If a database runs PostgreSQL 12, upgrade it before 1 March 2027: from that day RDS charges it the doubled Extended Support rate.
Originally published on codelevel.pl. Prices are net, for businesses. AWS, Hetzner and OVH are trademarks of their owners; CODELEVEL is not a partner, reseller or representative of any of them.
