<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: hamza waheed</title>
    <description>The latest articles on DEV Community by hamza waheed (@hamzafounder).</description>
    <link>https://dev.to/hamzafounder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2913704%2F0ce1a43b-17c2-4077-8b7e-f65b8ca020a1.jpeg</url>
      <title>DEV Community: hamza waheed</title>
      <link>https://dev.to/hamzafounder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hamzafounder"/>
    <language>en</language>
    <item>
      <title>Why did my AWS bill go up? How to find the cause in 10 minutes</title>
      <dc:creator>hamza waheed</dc:creator>
      <pubDate>Mon, 09 Nov 2026 20:06:59 +0000</pubDate>
      <link>https://dev.to/hamzafounder/why-did-my-aws-bill-go-up-how-to-find-the-cause-in-10-minutes-648</link>
      <guid>https://dev.to/hamzafounder/why-did-my-aws-bill-go-up-how-to-find-the-cause-in-10-minutes-648</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The good news: AWS records exactly where every cent went. Finding the cause is a matter of narrowing it down in the right order — &lt;strong&gt;service, then usage type, then region&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: compare like with like
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Compare the &lt;strong&gt;same days&lt;/strong&gt; of each month instead: the 1st to the 10th of this month against the 1st to the 10th of last month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: find the service that moved
&lt;/h2&gt;

&lt;p&gt;In the console: &lt;strong&gt;Billing and Cost Management → Cost Explorer&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set the date range to the same days of this month and last month&lt;/li&gt;
&lt;li&gt;Granularity: &lt;strong&gt;Daily&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Group by: &lt;strong&gt;Service&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The service whose bar grew is your answer to the first question. Daily granularity also shows you &lt;strong&gt;the day it started&lt;/strong&gt;, which usually tells you what caused it — a deploy, a migration, a new feature going live.&lt;/p&gt;

&lt;p&gt;From the command line, run this once for each period and compare the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ce get-cost-and-usage &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--time-period&lt;/span&gt; &lt;span class="nv"&gt;Start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2026-11-01,End&lt;span class="o"&gt;=&lt;/span&gt;2026-11-11 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--granularity&lt;/span&gt; MONTHLY &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metrics&lt;/span&gt; UnblendedCost &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-by&lt;/span&gt; &lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;DIMENSION,Key&lt;span class="o"&gt;=&lt;/span&gt;SERVICE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'ResultsByTime[].Groups[].[Keys[0], Metrics.UnblendedCost.Amount]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-k2&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;End&lt;/code&gt; date is exclusive, so &lt;code&gt;End=2026-11-11&lt;/code&gt; includes the 10th. Change the dates to &lt;code&gt;2026-10-01&lt;/code&gt; and &lt;code&gt;2026-10-11&lt;/code&gt; for the same window last month.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: find what inside that service
&lt;/h2&gt;

&lt;p&gt;"EC2" on its own isn't an answer. It covers instances, disks, snapshots, IP addresses and data transfer. Group the service you found by &lt;strong&gt;usage type&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ce get-cost-and-usage &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--time-period&lt;/span&gt; &lt;span class="nv"&gt;Start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2026-11-01,End&lt;span class="o"&gt;=&lt;/span&gt;2026-11-11 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--granularity&lt;/span&gt; MONTHLY &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metrics&lt;/span&gt; UnblendedCost &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s1"&gt;'{"Dimensions":{"Key":"SERVICE","Values":["EC2 - Other"]}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-by&lt;/span&gt; &lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;DIMENSION,Key&lt;span class="o"&gt;=&lt;/span&gt;USAGE_TYPE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'ResultsByTime[].Groups[].[Keys[0], Metrics.UnblendedCost.Amount]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="nt"&gt;-k2&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;EC2 - Other&lt;/code&gt; with the service name exactly as it appeared in Step 2. The usage type tells you what is actually billing — &lt;code&gt;NatGateway-Bytes&lt;/code&gt;, &lt;code&gt;EBS:VolumeUsage.gp2&lt;/code&gt;, &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; and so on.&lt;/p&gt;

&lt;p&gt;Then group by &lt;code&gt;REGION&lt;/code&gt; instead of &lt;code&gt;USAGE_TYPE&lt;/code&gt;. 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The usual culprits
&lt;/h2&gt;

&lt;p&gt;Most unexplained increases come down to a short list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NAT Gateway data processing.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data transfer.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto Scaling that scaled up and never came down.&lt;/strong&gt; A wrong metric or a missing maximum keeps adding instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Things left behind.&lt;/strong&gt; Stopped instances still bill for their disks, deleted instances often leave their data volumes behind, and old snapshots pile up. See &lt;a href="https://devopsly.app/guides/stopped-ec2-instance-still-charging" rel="noopener noreferrer"&gt;why a stopped EC2 instance still costs money&lt;/a&gt; and &lt;a href="https://devopsly.app/guides/find-unattached-ebs-volumes" rel="noopener noreferrer"&gt;how to find unattached EBS volumes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public IPv4 addresses.&lt;/strong&gt; AWS charges for every public IPv4 address, including ones attached to running instances — not only unused Elastic IPs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Logs.&lt;/strong&gt; Debug logging left on in production, with retention set to "never expire", grows every single day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free tier or credits ending.&lt;/strong&gt; If nothing changed in usage but the bill appeared, check whether a free tier period or promotional credits ran out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaked credentials.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to stop finding out at month end
&lt;/h2&gt;

&lt;p&gt;Finding the cause is the easy part. The expensive part is the three weeks before anyone looked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn on AWS Cost Anomaly Detection.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a budget with daily alerts&lt;/strong&gt;, not only monthly. A monthly budget tells you after the money has gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set limits where you can.&lt;/strong&gt; A maximum on every Auto Scaling group means a runaway config stops at a number you chose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting told, with the cause attached
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Devopsly checks your spending every day.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://demo.storylane.com/share/cjzopptvnhqm" rel="noopener noreferrer"&gt;See what it finds in a real account →&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>finops</category>
    </item>
  </channel>
</rss>
