AWS costs: The 10 most common surprise charges, ranked by forum screams
The AWS charges that generate the most forum complaints are almost never the ones people expect — they're not big EC2 instances or forgotten Lambda loops. They're small, recurring, per-hour or per-GB fees for things that look free at first glance: a public IP address sitting on an instance, a NAT Gateway idling with nothing routed through it, an EBS volume nobody remembers creating. The single most counterintuitive one on this list didn't even exist for the first thirteen years of AWS's existence — plenty of accounts started getting billed for it without changing a single line of infrastructure.
How this ranking works (and what it doesn't claim)
Before the list: this isn't the output of a scientific survey of every AWS support forum. It reflects which charges keep coming back as the same basic question, phrased a dozen different ways, from people who did nothing wrong and still got billed. Some of these charges are tiny per-hour amounts that only become "screams" once they've been running quietly for three months. Others are one-time fees that arrive out of nowhere the moment someone tries to clean up their account. Both kinds belong on this list, because both kinds generate the same reaction: "I didn't launch anything — why am I being charged for this?"
Every dollar figure below comes from AWS's own pricing pages and documentation, not from third-party blog estimates, and every one is a rate, not a guarantee of what your bill will be — actual costs depend on your region, your usage, and how long a resource has been sitting there before you noticed it. Where a fix involves an AWS-native monitoring feature rather than a manual check, that's noted too, since a couple of these charges are genuinely easier to catch with automation than by memory.
♂️ Jake's Reality Check
"I followed a YouTube tutorial to put a simple trade-in-value checker for my shop on AWS. I never touched the console again after it worked. Six months later I owe $41 and I have genuinely no idea what any of it is for."
That's not a mystery bill — it's ten small charges stacking quietly. None of them are fraud, none of them are a billing error. They're all things AWS documents, just not things anyone reads before clicking "Launch."
10. CloudWatch Logs set to "Never Expire" — the bill that grows even when nothing changes
This one ranks at the bottom of the "screams" list because it doesn't announce itself. It just makes every month slightly worse than the one before it. Every Lambda function, every ECS task, every EC2 app that writes logs, sends them somewhere — and by default, that somewhere is a CloudWatch Logs log group with a retention setting of Never Expire.
Amazon CloudWatch's own pricing page lists a free tier of 5 GB of log data per month, covering ingestion, storage, and data scanned by Logs Insights queries. Past that, standard log ingestion is billed per GB, and archived storage is billed separately per GB per month, for as long as the logs sit there — which, with "Never Expire" selected, is forever. AWS support staff answering this exact question on re:Post have confirmed the mechanism plainly: if retention is set to never expire, logs keep accumulating because nothing deletes them, and the monthly charge grows as a result.
What it looks like when this one is quietly failing
The tell isn't a spike — it's a slope. Cost Explorer shows CloudWatch as a small but steadily climbing line, month over month, without a matching increase in traffic or a matching new resource anywhere else in the account. That slow-and-steady shape is exactly what a growing "Never Expire" log group produces, because the storage charge compounds on top of itself: you're not just paying for this month's logs, you're paying for every month's logs, forever, in addition.
The fix, cheapest first
Set a retention period on every log group you own — 14 or 30 days is enough for almost any debugging workflow. This is a per-log-group setting, not an account-wide default, so a new Lambda function or new ECS service creates a fresh "Never Expire" group unless you set it explicitly or via infrastructure-as-code every time. That's the edge case worth knowing: fixing the log groups that exist today doesn't fix the ones a teammate's deploy script creates next week, so the retention setting needs to live in the template, not just be clicked once in the console.
✅ Why this is the one to use
A 30-day retention policy costs nothing extra to set and typically has zero effect on debugging — almost nobody goes back further than a month to trace a bug. It's the single cheapest fix on this entire list because it stops a cost that never had a reason to start.
One privacy-adjacent note worth flagging before mass-editing retention on every log group: if any of your logs are kept longer deliberately, for a compliance or audit trail requirement rather than by accident, check with whoever owns that requirement before shortening retention across the board. The fix above is for logs nobody meant to keep forever — not a blanket instruction to shrink every log group in the account.
9. S3 Glacier "early deletion" fees — the penalty for cleaning up too soon
People move data into S3 Glacier storage classes specifically to save money, then get an unexpected line item the moment they delete or move it back out. Both S3 Glacier Instant Retrieval and S3 Glacier Flexible Retrieval carry a minimum storage duration of 90 days; S3 Glacier Deep Archive carries a minimum of 180 days. Delete, overwrite, or transition an object to a different storage class before that window closes, and Amazon charges a pro-rated fee equal to the storage cost for the remaining days — on top of whatever you already paid for storage.
The math is straightforward once you see it laid out: if a 100 GB object goes into Deep Archive at roughly $0.0018/GB-month and gets deleted on day 1, you owe the storage charge for the full 180 days, calculated as if it had sat there the whole time. AWS's own knowledge-center article on this exact question spells out the formula plainly, because it is one of the most-asked billing questions in the S3 forums.
⚠️ What this actually breaks
Lifecycle rules that transition data through several storage classes in quick succession (Standard → Standard-IA → Glacier → Deep Archive) can trigger this fee at every hop if the object doesn't survive each tier's minimum duration. A poorly spaced lifecycle policy is a self-inflicted version of this charge — the exact thing the policy was supposed to prevent.
Restoring an object out of Glacier into S3 Standard resets the clock for that copy — once it's back in Standard, you can delete the restored copy freely without a second early-deletion fee, because that fee is tied to the archive tier specifically, not the restored copy. The edge case that trips people up: the original archived object is untouched by that restore. If you then go back and delete the archived original before its own 90- or 180-day clock has finished, that early-deletion charge still applies, separately from anything you did with the restored copy.
The adjacent task worth doing at the same time
If you're reviewing lifecycle rules because of this fee, it's worth checking the transition timing against how the data actually gets used, not just how old it is. A rule that moves logs to Glacier after 30 days sounds tidy, but if the same logs sometimes get pulled back for an investigation within 90 days, every one of those pulls risks resetting into a fee cycle. Spacing transitions to match the minimum durations — not shorter — is the whole fix.
8. RDS backup storage that outlives the database it backed up
Amazon RDS gives every region a pool of free backup storage equal to 100% of your total provisioned database storage in that region. That sounds generous until you notice two things AWS's own documentation spells out: first, that pool is shared across every RDS instance in the region, not per-database; second, automated backups and manual DB snapshots both draw from the same pool.
The trap: a manual snapshot is completely independent of the database instance it came from. AWS's documentation is explicit that deleting a DB instance without choosing to retain automated backups deletes those automated backups — but manual snapshots (and any final snapshot you chose to keep) are unaffected by that deletion and keep counting against your backup storage, and keep costing money, indefinitely, until someone deletes them by hand.
Ethan's take
"People assume 'I deleted the database' means 'I stopped paying for the database.' RDS was built the other way around — the snapshot is the durable thing, and the running instance is the disposable thing. If you wanted the backup gone too, you had to say so explicitly."
Once you exceed the free pool, the excess backup storage bills at a standard per-GB-month rate. For an account running several databases with long retention windows and a habit of taking "just in case" manual snapshots before every change, this pool fills up faster than most people expect — and here's the part that catches people twice: shrinking your active database footprint (deleting an unneeded instance, downsizing another) also shrinks the free pool at the same time, since it's calculated against your current provisioned storage. So the free allowance can drop right as your leftover snapshot pile stays exactly the same size, pushing you over the line from two directions at once.
Before mass-deleting old manual snapshots to fix this, it's worth a quick check with whoever owns compliance or data-retention requirements on the team — a snapshot that looks orphaned to Cost Explorer might still be satisfying a "keep backups for N days" policy nobody wrote down in the console.
7. EBS snapshots that quietly grow, then get archived and can't be cheaply undone
EBS snapshots are billed per GB-month, and they're incremental: the first snapshot of a volume is billed for the volume's full size, but every snapshot after that is billed only for the blocks that changed since the last one. That part is genuinely cost-friendly and documented plainly by AWS. The surprise comes from two other pieces of the same system.
First, moving snapshots into the Archive tier to save money comes with a 90-day minimum archive period. Delete or fully restore an archived snapshot before that window closes, and you're billed a pro-rated charge for the remaining days at the archive rate, plus the one-time retrieval fee if you restored it. Second, once a snapshot is fully restored out of the archive tier back to standard, it's billed at the standard snapshot rate going forward — so an "I'll just archive everything to save money" habit can end up costing more than doing nothing, if those snapshots get touched again inside 90 days.
| Snapshot state | How it's billed | The trap |
|---|---|---|
| Standard tier | Per GB-month, incremental after the first snapshot | Old snapshots from deleted volumes never expire on their own |
| Archive tier | Lower per GB-month rate, plus a one-time restore fee | 90-day minimum; early delete or restore is pro-rated for the rest of that window |
| Restored from archive | Standard snapshot rate resumes | "Restore then delete quickly" doesn't undo the archive commitment |
The edge case worth naming: a shared snapshot from another AWS account doesn't cost you anything until you copy it into your own account. Once copied, the copy is a full, independent snapshot and bills exactly like one you created yourself — a detail that surprises people restoring a colleague's or a vendor's shared image and expecting it to stay free indefinitely.
Automating the cleanup instead of remembering it
Rather than manually auditing snapshots on a schedule, AWS Data Lifecycle Manager can be set up to create, retain, and delete snapshots on a policy — for example, keep the last 7 daily snapshots and automatically expire anything older. That turns "someone has to remember to clean this up" into a rule that enforces itself, which matters most for exactly the kind of small, easy-to-forget resource this whole list is about.
6. EBS volumes that survive a terminated instance
This is one of the most common "why is EBS still charging me, I terminated everything" complaints, and the cause is a single default setting most people never see. When you terminate an EC2 instance, AWS's own guidance is explicit: the DeleteOnTermination attribute controls whether each attached volume is deleted along with the instance or left behind, and by default that attribute is True only for the root volume. Every other attached volume defaults to False — meaning it survives termination and keeps billing as a standalone EBS volume, completely detached from any instance, for as long as it exists.
How to find these before they add up
- Open the EC2 console and go to Elastic Block Store → Volumes.
- Filter or sort by State — anything showing available (not in-use) is unattached and billing on its own.
- For each one, check the Created date and any tags to figure out which now-terminated instance it came from.
- If you don't need it, take a final snapshot if there's any chance you'll want the data later, then delete the volume.
- Going forward, set
DeleteOnTermination=trueexplicitly on non-root volumes at launch time if you don't have a reason to keep them independently.
Jake found four of these in his account — leftover data volumes from EC2 instances he'd spun up, tested, and terminated months earlier while following different tutorials. None of them were large, but together they were a real, ongoing line item for storage attached to nothing.
Why this is easy to catch with automation
Because "unattached for a while" is such a specific, mechanical condition, it's one of the cost checks AWS Trusted Advisor includes under its Cost Optimization category, alongside checks for unassociated Elastic IP addresses and inactive NAT Gateways. Trusted Advisor's full cost-optimization check set requires a paid Business or Enterprise-level Support plan rather than the free Basic tier, so it's not automatically running in every account — but for anyone already on one of those plans, this exact check exists and is worth turning on rather than doing the manual console sweep every quarter.
5. "I stopped the instance" doesn't mean "I stopped paying"
This is one of the most persistent pieces of wrong popular advice floating around: that stopping an EC2 instance is functionally the same as pausing all charges for it. It isn't, and AWS support staff address this exact confusion repeatedly on re:Post. Stopping an instance does stop the compute (instance-hour) charge — that part of the advice is correct. What it does not stop:
- The attached EBS volumes, which keep billing for provisioned storage whether the instance is running or not.
- Any snapshots taken of those volumes.
- An Elastic IP address attached to the stopped instance — which, once the instance is no longer running, is treated the same as an unattached address for billing purposes (see #4 below).
♂️ Jake's Reality Check
"I stopped the instance for the weekend because I wasn't using it. I figured that meant the meter stopped too."
The compute meter stopped. Nothing else did. A stopped instance with a 100 GB attached volume and an Elastic IP is still generating two separate small charges every single hour it sits there, forever, until you either terminate it properly or detach and release what's attached to it.
The edge case that makes this worse than it sounds: a stopped instance still counts toward any On-Demand vCPU service quota you have, and if that instance was ever configured with detailed monitoring or additional EBS-optimized throughput, those settings don't pause either — they just have nothing to bill against until the instance runs again, while the storage underneath keeps accumulating cost the entire time it sits stopped.
4. Unattached Elastic IP addresses — small, per-hour, and easy to forget
Long before the broader public IPv4 charge existed (see #1), AWS already charged a small hourly fee — $0.005 per hour — for an Elastic IP address that isn't attached to a running instance, or that's attached to a stopped instance, or that's sitting on an unattached network interface. AWS's own pricing page states this plainly: the charge exists "to ensure efficient use of Elastic IP addresses," and it applies the moment the address stops being actively used by a running resource.
The most common way this happens: someone allocates an Elastic IP, attaches it to an instance to test something, then terminates the instance without releasing the address first. The IP address itself isn't deleted along with the instance — it just becomes an orphaned resource sitting in your account's IP pool, billing quietly at $0.005 an hour (roughly $3.60 a month) until someone finds it and releases it.
The failure mode worth knowing
Releasing an Elastic IP is permanent and immediate — once released, it goes back into AWS's general pool and there's no guarantee you'll be able to reclaim the same address if it turns out something still depended on it (a DNS A record pointed at it, a firewall allowlist entry, a partner's webhook configuration). Before releasing an address you're not sure about, it's worth a quick search across your own DNS zones and any external allowlists first — the $3.60 a month this charge costs is trivial compared to the time spent tracking down a broken integration after the fact.
3. Data transfer out to the internet, once the free 100 GB runs out
AWS gives every account 100 GB of data transfer out to the internet free per month, aggregated across most services and regions. Past that, the published rate is $0.09 per GB for the first 10 TB in a month, with lower tiered rates as volume increases further. That 100 GB free allowance sounds like plenty for a small project — until a site gets linked somewhere, or a background job starts pulling more than it uploads, and the free allowance disappears in a single busy day.
What catches people off guard specifically is that this counter is aggregated across services — EC2, S3, RDS, and several others all draw down the same 100 GB pool. A small EC2-hosted app serving images directly from an attached volume, plus a separate S3 bucket serving downloads, both eat into the same free allowance rather than each getting their own.
What changed between versions
- The free 100 GB per month allowance and the tiered per-GB rates above it are AWS's current published EC2 data transfer pricing, aggregated across the listed services and regions.
- Traffic between two resources in the same Availability Zone using private IP addresses has no data transfer charge at all — the charge only starts once traffic leaves the AZ, leaves the region, or leaves AWS entirely.
- Cross-AZ transfer within the same region is billed separately (see the NAT Gateway section below) at a much lower rate than internet egress, but it still isn't free.
The adjacent question worth asking once this fee shows up: is a Content Delivery Network actually a better fit than serving files straight off an EC2 instance or an unfronted S3 bucket? That's a bigger architectural decision than this post can settle in a paragraph, but the general shape is worth knowing — routing static content through a CDN changes which meter the traffic hits and can change the effective rate, so it's worth investigating specifically rather than assuming "data transfer is data transfer" everywhere.
2. NAT Gateway data processing charges — billed by the gigabyte, no matter where the traffic goes
A NAT Gateway is what lets instances in a private subnet reach the internet without themselves having a public IP address. AWS's own VPC pricing page lays out exactly three charges that stack on top of each other every time it's used: an hourly charge for the gateway simply existing (billed as a full hour even for a partial one), a per-GB "data processing" charge for every gigabyte that passes through it in either direction, and then whatever standard data transfer charge applies on top of that, depending on where the traffic is actually going.
AWS's own pricing example spells out the layering: a 1 GB file sent from an EC2 instance through a NAT Gateway to an S3 bucket in the same region and Availability Zone incurs the NAT Gateway's hourly charge plus its per-GB data processing charge — but no separate data transfer charge in that specific case, because that particular path (EC2 to S3, same region) doesn't carry one. Change any one of those conditions — a different Availability Zone, a destination outside AWS — and an additional, separate charge appears.
Ethan's take
"NAT Gateway is the least glamorous line item in a lot of accounts, and it's also one of the most expensive per byte, because you're paying three separate meters for the same gigabyte. If most of your NAT traffic is actually just going to S3 or DynamoDB, you're paying for a service you don't need — a Gateway VPC endpoint routes that traffic for free instead."
| Path | NAT Gateway hourly + processing? | Use it when |
|---|---|---|
| Private subnet → S3 or DynamoDB, same region | Yes, unless routed via a Gateway VPC endpoint (no hourly/processing fee) | Almost never — use the endpoint instead |
| Private subnet → other AWS services (SQS, SNS, etc.) | Yes, or a lower per-GB rate via an Interface VPC endpoint | High-volume traffic to a single AWS service |
| Private subnet → general internet (APIs, package registries) | Yes — no substitute exists for genuine internet-bound traffic | This is what NAT Gateway is actually for |
The other trap layered on top: if the NAT Gateway sits in a different Availability Zone than the instance using it, cross-AZ data transfer charges apply in both directions, in addition to the NAT Gateway's own per-GB processing fee — two separate meters running on the exact same bytes. And because a NAT Gateway's hourly charge runs regardless of traffic, a NAT Gateway left behind in a decommissioned test VPC bills the same whether it's processing a terabyte or sitting completely idle — which is exactly the condition AWS Trusted Advisor's "Inactive NAT Gateways" check is built to flag for accounts on a paid Support plan.
1. The public IPv4 address charge — the one that hits accounts that changed nothing
This is the reveal from the top of the post, in full. For the first roughly thirteen years of AWS's existence, a public IPv4 address attached to a running EC2 instance — the ordinary, default kind you get automatically when you launch an instance in a public subnet — was free. AWS's own News Blog announcement is direct about what changed: effective February 1, 2024, a charge of $0.005 per IP per hour applies to every in-use public IPv4 address, whether it's an Amazon-provided public IP or an Elastic IP, attached to EC2, RDS, EKS nodes, or several other services, in every commercial AWS region plus AWS China and GovCloud.
What changed between versions
- Before February 1, 2024: an in-use public IPv4 address attached to a running resource was free. Only idle Elastic IPs and secondary Elastic IPs on a running instance were ever billed.
- From February 1, 2024: every in-use public IPv4 address is billed at $0.005/hour — roughly $3.60/month per address — regardless of whether it's actively serving traffic.
- What didn't change: idle Elastic IPs and secondary Elastic IPs were already billed at the same $0.005/hour rate before this change, so for accounts that already had unattached EIPs, this specific update didn't add a new charge type — it extended the existing rate to a much larger set of addresses.
- AWS also updated the EC2 Free Tier to include 750 hours per month of public IPv4 usage for the first 12 months, to offset the change for new Free Tier accounts.
Per-address, per-hour, this is the smallest charge on the entire list. That's exactly why it generates the most forum activity: it's easy to dismiss as "too small to matter" right up until an account has a dozen small EC2 instances, each with its own public IP, each one now costing roughly $3.60 a month it wasn't costing before — a bill that changed even though the infrastructure behind it stayed exactly the same.
The edge case worth knowing before switching everything to IPv6 to dodge this fee entirely: not every client, corporate network, or third-party integration your instance talks to necessarily supports IPv6 yet. Dropping a public IPv4 address only works cleanly if whatever needs to reach that resource can actually reach it over IPv6 or through a private path instead — otherwise the fix trades a small, predictable monthly charge for a connectivity outage, which is a worse trade.
✅ Why this is the one to use
If an instance genuinely doesn't need to be reachable from the public internet, removing its public IP and reaching it instead through a bastion host, Session Manager, or a VPN eliminates this charge entirely — and is also, independently, the safer architecture for anything that doesn't need to face the internet. That's the adjacent task worth doing at the same time: once a public IP comes off an instance, it's worth re-checking that instance's security group too, since a rule that used to matter for internet-facing traffic may no longer need to exist at all.
How to catch these before the bill arrives
None of the ten charges above are hidden in the sense of being undocumented — every one of them is on an AWS pricing page somewhere. What's actually missing for most accounts isn't information, it's a habit of looking. Three habits, in order of setup effort, catch almost everything on this list before it becomes a "scream":
Set up a budget alert
- In the AWS Billing and Cost Management console, open AWS Budgets and create a new cost budget.
- Set a monthly amount that reflects what you actually expect to spend — even a small threshold like $5 or $10 is useful for a personal project account.
- Add an alert threshold at 50% and another at 100% of the budgeted amount, each sent to an email address you actually check.
- Repeat with a second budget scoped to a specific service (like EC2 or VPC) if one category worries you more than the total.
Turn on Cost Anomaly Detection
A budget alert only fires once you cross a fixed number you set yourself. AWS Cost Anomaly Detection works differently: it's a free feature that uses a machine-learning model to learn your account's normal day-to-day spending pattern — by service, by linked account, or by cost allocation tag — and it flags a spend pattern that breaks from that learned baseline, even if the total dollar amount would never have crossed a budget threshold. AWS's own documentation notes that once a cost monitor and alert subscription are set up, detection begins working within about 24 hours, with alerts delivered by email or an Amazon SNS topic, and each flagged anomaly comes with a root-cause breakdown showing the biggest contributors to the unexpected spend. For something like a NAT Gateway that starts processing far more data than usual, or a CloudWatch Logs group that suddenly starts ingesting at ten times its normal rate, this catches the shift immediately rather than waiting for it to accumulate into a noticeable total.
Do a quarterly orphan sweep
- In Cost Explorer, group charges by Service, then by Usage Type, for the last three months, and look for anything unfamiliar or slowly climbing.
- In the EC2 console, check Elastic IPs for anything not shown as associated with a running instance.
- Check Volumes for anything in the available state.
- Check Snapshots for anything tied to a volume ID that no longer exists.
- In RDS, check Snapshots for manual snapshots from databases that were deleted long ago.
If your account is on a Business or Enterprise-level AWS Support plan, most of this sweep is already automated: AWS Trusted Advisor's Cost Optimization category includes standing checks for unassociated Elastic IP addresses, underutilized EBS volumes, and inactive NAT Gateways, among others, and re-running those checks takes a few clicks instead of a manual console tour. On the free Basic Support tier, those specific checks aren't included, which is the honest reason the manual sweep above still matters for smaller accounts and personal projects — it's doing by hand what a paid support tier would otherwise do for you.
Do you need a third-party cost tool on top of all this?
Third-party FinOps dashboards exist, and for an organization running dozens of linked accounts across multiple teams, they genuinely add value — shared views, chargeback reporting, and workflow integrations that AWS's native tools aren't built to provide. For a single account, a side project, or a small shop's one AWS bill, that's almost always more tool than the problem calls for. AWS Budgets, Cost Anomaly Detection, and Cost Explorer are already free, already built into the console, and already cover every charge on this list. The honest advice: reach for a third-party tool once cost tracking becomes a job someone owns across a team, not before.
None of these habits prevent a charge from ever happening — they just shrink the gap between "this started billing" and "someone noticed," which is where almost all of the frustration on this list actually lives.
Frequently asked questions
Why did my AWS bill go up when I didn't launch anything new?
Most often it's a per-hour or per-GB-month charge that was already running quietly — a NAT Gateway, an idle Elastic IP, an EBS volume from a terminated instance, or CloudWatch Logs with no retention limit — and it simply accumulated to a noticeable amount. Nothing new has to launch for an existing small charge to add up over several billing cycles.
Does stopping an EC2 instance stop all charges for it?
No. It stops the compute (instance-hour) charge only. Attached EBS volumes, any snapshots of them, and an Elastic IP attached to the now-stopped instance all keep billing exactly as before.
Why am I being charged for an Elastic IP I'm not using?
Elastic IP addresses that aren't attached to a running instance, or that are attached to a stopped instance, are billed at $0.005 per hour. This is intended to discourage holding IP addresses that aren't actively in use.
Is my EC2 instance's public IP address free?
Not since February 1, 2024. Every in-use public IPv4 address, including the default one automatically assigned to an instance in a public subnet, is billed at $0.005 per hour.
How do I avoid NAT Gateway data processing charges?
For traffic bound for S3 or DynamoDB, route it through a Gateway VPC endpoint instead, which has no hourly or per-GB processing charge. For traffic to other AWS services, an Interface VPC endpoint carries a lower per-GB rate than NAT Gateway. For genuine internet-bound traffic, there's no substitute — that's what NAT Gateway is for.
Why do I have EBS volumes with no instance attached?
By default, only an instance's root volume is set to delete automatically on termination. Additional attached volumes default to surviving termination, becoming standalone billed resources unless you explicitly configure them to delete along with the instance.
Does deleting an EC2 instance delete its snapshots?
No, snapshots are independent resources. Deleting the instance, and even deleting the volume the snapshot was taken from, does not delete the snapshot itself — it has to be deleted separately.
Why did my RDS backup storage suddenly start costing money?
The free backup storage pool for a region equals the total provisioned database storage in that region, shared across both automated backups and manual snapshots. Deleting a database instance doesn't reduce that pool if manual snapshots or retained automated backups remain — and if your total provisioned database storage in the region drops, so does your free allowance, while old snapshots keep taking up the same space.
What happens if I delete a Glacier object early?
You're charged a pro-rated fee equal to the storage cost for the remaining days of that storage class's minimum duration — 90 days for Glacier Instant Retrieval and Glacier Flexible Retrieval, 180 days for Glacier Deep Archive.
Why is my CloudWatch Logs bill growing every month with no new resources?
Log groups with retention set to "Never Expire" keep every log event forever, so both ingestion and storage costs accumulate month over month even if the amount of new logging stays flat.
Is data transfer between two EC2 instances in the same region free?
Only if they're in the same Availability Zone and communicating over private IP addresses. Cross-AZ traffic within the same region is billed per GB in each direction, even though it never technically leaves AWS.
Why is cross-AZ traffic through my NAT Gateway more expensive?
If an instance and its NAT Gateway sit in different Availability Zones, the traffic incurs the standard cross-AZ data transfer charge in addition to the NAT Gateway's own hourly and per-GB data processing charges — two separate charges on the same bytes.
Can I get a refund for a surprise AWS charge?
Refunds aren't guaranteed, and this isn't something we can promise either way. If a charge came from a genuine misunderstanding rather than intended usage, opening a billing support case and explaining the situation is the only path — AWS Support handles these case by case.
What's the fastest way to see which service is causing a charge?
Open Cost Explorer, group by Service, and sort by cost descending for the current month. From there, drill into the highest unfamiliar line item by Usage Type to see exactly what's being billed.
Do AWS Budgets alerts stop charges automatically?
No. A budget alert only sends a notification once a threshold is crossed — it doesn't stop, pause, or delete anything on its own. Acting on the alert is still a manual step, and it's also fixed to a threshold you set, unlike Cost Anomaly Detection, which learns your spending pattern instead of relying on a static number.
Will switching to IPv6 actually save me money?
For the public IPv4 address charge specifically, yes — resources reachable only over IPv6 don't carry that per-hour fee, since it applies to public IPv4 addresses. It won't affect the other charges on this list, like NAT Gateway processing fees or EBS storage, which are unrelated to IP address family, and it only works cleanly if everything that needs to reach that resource can actually do so over IPv6.
- AWS costs: KMS - the $1/key/month and the request charges
- AWS costs: Secrets Manager vs Parameter Store - $0.40/secret decided
- AWS costs: Config pricing deep-dive - tuning the recorder
- AWS costs: GuardDuty/Inspector/Security Hub - the full security bill on one page
- AWS costs: AWS Backup pricing - and restore charges
- AWS costs: Athena - $5/TB scanned, and partitioning that divides it
- AWS costs: OpenSearch - the smallest honest cluster price
- AWS costs: Free tier 2025+ - credits model fully explained
- AWS costs: Billing alerts that actually fire - the 3-layer setup
- AWS costs: Cost allocation tags - seeing which project spends
- AWS costs: The 10 most common surprise charges, ranked by forum screams
- AWS costs: How to read Cost Explorer - a 15-minute literacy course
- AWS costs: Reserved vs Savings Plans vs Spot - one decision tree
Revision note. Written September 2026, covering current AWS pricing for EC2, VPC (NAT Gateway, Elastic IP, public IPv4), EBS, RDS, S3 Glacier, and CloudWatch Logs. Rates and free-tier allowances change with AWS pricing updates, so it's worth checking the linked pricing pages again if it's been a while since this was written. If you're staring at a bill line you don't recognize right now — take a breath, it's very likely one of the ten above, and every one of them has a clean, permanent fix.Happy learning, See you on next post!