<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hamza on AWS costs]]></title><description><![CDATA[Hamza on AWS costs]]></description><link>https://hamzafounder.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6af2250e67b90e779f8c4baf/ea26632d-1abe-4468-a472-eff783abf93f.png</url><title>Hamza on AWS costs</title><link>https://hamzafounder.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 08:19:51 GMT</lastBuildDate><atom:link href="https://hamzafounder.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Why did my AWS bill go up? How to find the cause in 10 minutes]]></title><description><![CDATA[Your bill is higher than last month and nothing obvious changed. Traffic is flat, nobody launched anything big, and the invoice is one long list of line…]]></description><link>https://hamzafounder.hashnode.dev/why-did-my-aws-bill-go-up-how-to-find-the-cause-in-10-minutes</link><guid isPermaLink="true">https://hamzafounder.hashnode.dev/why-did-my-aws-bill-go-up-how-to-find-the-cause-in-10-minutes</guid><category><![CDATA[AWS]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[finops]]></category><dc:creator><![CDATA[Hamzatwenty]]></dc:creator><pubDate>Mon, 09 Nov 2026 20:15:58 GMT</pubDate><content:encoded><![CDATA[<p>Your bill is higher than last month and nothing obvious changed. Traffic is flat, nobody launched anything big, and the invoice is one long list of line items.</p>
<p>The good news: AWS records exactly where every cent went. Finding the cause is a matter of narrowing it down in the right order — <strong>service, then usage type, then region</strong>.</p>
<h2>Step 1: compare like with like</h2>
<p>The most common mistake is comparing this month so far with the whole of last month. Ten days of spending will always look smaller than thirty, and a real spike hides behind it.</p>
<p>Compare the <strong>same days</strong> of each month instead: the 1st to the 10th of this month against the 1st to the 10th of last month.</p>
<h2>Step 2: find the service that moved</h2>
<p>In the console: <strong>Billing and Cost Management → Cost Explorer</strong>.</p>
<ol>
<li>Set the date range to the same days of this month and last month</li>
<li>Granularity: <strong>Daily</strong></li>
<li>Group by: <strong>Service</strong></li>
</ol>
<p>The service whose bar grew is your answer to the first question. Daily granularity also shows you <strong>the day it started</strong>, which usually tells you what caused it — a deploy, a migration, a new feature going live.</p>
<p>From the command line, run this once for each period and compare the two:</p>
<pre><code class="language-bash">aws ce get-cost-and-usage \
  --time-period Start=2026-11-01,End=2026-11-11 \
  --granularity MONTHLY \
  --metrics UnblendedCost \
  --group-by Type=DIMENSION,Key=SERVICE \
  --query 'ResultsByTime[].Groups[].[Keys[0], Metrics.UnblendedCost.Amount]' \
  --output text | sort -t$'\t' -k2 -rn
</code></pre>
<p>The <code>End</code> date is exclusive, so <code>End=2026-11-11</code> includes the 10th. Change the dates to <code>2026-10-01</code> and <code>2026-10-11</code> for the same window last month.</p>
<p>Each Cost Explorer API request costs $0.01. Running this a few times costs nothing worth worrying about — but don't put it in a loop that runs every minute.</p>
<h2>Step 3: find what inside that service</h2>
<p>"EC2" on its own isn't an answer. It covers instances, disks, snapshots, IP addresses and data transfer. Group the service you found by <strong>usage type</strong>:</p>
<pre><code class="language-bash">aws ce get-cost-and-usage \
  --time-period Start=2026-11-01,End=2026-11-11 \
  --granularity MONTHLY \
  --metrics UnblendedCost \
  --filter '{"Dimensions":{"Key":"SERVICE","Values":["EC2 - Other"]}}' \
  --group-by Type=DIMENSION,Key=USAGE_TYPE \
  --query 'ResultsByTime[].Groups[].[Keys[0], Metrics.UnblendedCost.Amount]' \
  --output text | sort -t$'\t' -k2 -rn | head -n 10
</code></pre>
<p>Replace <code>EC2 - Other</code> with the service name exactly as it appeared in Step 2. The usage type tells you what is actually billing — <code>NatGateway-Bytes</code>, <code>EBS:VolumeUsage.gp2</code>, <code>DataTransfer-Regional-Bytes</code> and so on.</p>
<p>Then group by <code>REGION</code> instead of <code>USAGE_TYPE</code>. A cost in a region your team doesn't use is worth investigating straight away — that's where forgotten resources live, and it's where an attacker running up your bill would put them.</p>
<h2>The usual culprits</h2>
<p>Most unexplained increases come down to a short list:</p>
<ul>
<li><strong>NAT Gateway data processing.</strong> Traffic from private subnets to S3, ECR or other AWS services goes through the NAT and is charged per GB. A new service pulling container images or writing logs can quietly double it. A free gateway endpoint for S3 fixes most of it.</li>
<li><strong>Data transfer.</strong> Traffic between availability zones and between regions is charged in both directions. A new replica or a chatty service in another AZ shows up here.</li>
<li><strong>Auto Scaling that scaled up and never came down.</strong> A wrong metric or a missing maximum keeps adding instances.</li>
<li><strong>Things left behind.</strong> Stopped instances still bill for their disks, deleted instances often leave their data volumes behind, and old snapshots pile up. See <a href="https://devopsly.app/guides/stopped-ec2-instance-still-charging">why a stopped EC2 instance still costs money</a> and <a href="https://devopsly.app/guides/find-unattached-ebs-volumes">how to find unattached EBS volumes</a>.</li>
<li><strong>Public IPv4 addresses.</strong> AWS charges for every public IPv4 address, including ones attached to running instances — not only unused Elastic IPs.</li>
<li><strong>CloudWatch Logs.</strong> Debug logging left on in production, with retention set to "never expire", grows every single day.</li>
<li><strong>Free tier or credits ending.</strong> If nothing changed in usage but the bill appeared, check whether a free tier period or promotional credits ran out.</li>
<li><strong>Leaked credentials.</strong> A sudden spend in an unfamiliar region, or on a service you've never used — often EC2 GPU instances or Bedrock — means someone else is using your account. Deactivate the keys and open a support case immediately.</li>
</ul>
<h2>How to stop finding out at month end</h2>
<p>Finding the cause is the easy part. The expensive part is the three weeks before anyone looked.</p>
<p><strong>Turn on AWS Cost Anomaly Detection.</strong> It's free, it's in Billing and Cost Management, and it learns your normal spend per service. Point its alerts at an email address someone actually reads.</p>
<p><strong>Add a budget with daily alerts</strong>, not only monthly. A monthly budget tells you after the money has gone.</p>
<p><strong>Set limits where you can.</strong> A maximum on every Auto Scaling group means a runaway config stops at a number you chose.</p>
<h2>Getting told, with the cause attached</h2>
<p><strong>Devopsly checks your spending every day.</strong> Connect your AWS account read-only and it compares each service against the same days of the previous three months — like for like, so a spike shows up on day three, not day thirty. Anything up at least 20% and at least $5 is flagged with the service, what you spent and what you'd normally spend. On Starter and Growth you get it by email or Slack.</p>
<p>It also flags the leftovers from the list above — stopped instances, unattached volumes — in the same place, so a spike and its likely cause aren't in two different tools.</p>
<p>It ignores decreases and services that are brand new this month, because there's nothing to compare them against. It uses 15 read-only IAM actions and never touches your infrastructure or opens your files.</p>
<p><a href="https://demo.storylane.com/share/cjzopptvnhqm">See what it finds in a real account →</a></p>
]]></content:encoded></item></channel></rss>