<?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: Craig Milam</title>
    <description>The latest articles on DEV Community by Craig Milam (@cmilam).</description>
    <link>https://dev.to/cmilam</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%2F4103353%2F0010ded9-3447-411b-829c-9cddea2483b0.jpg</url>
      <title>DEV Community: Craig Milam</title>
      <link>https://dev.to/cmilam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cmilam"/>
    <language>en</language>
    <item>
      <title>8 Places AWS Bills Hide Money That Nobody's Watching</title>
      <dc:creator>Craig Milam</dc:creator>
      <pubDate>Mon, 31 Aug 2026 21:39:49 +0000</pubDate>
      <link>https://dev.to/cmilam/8-places-aws-bills-hide-money-that-nobodys-watching-4do5</link>
      <guid>https://dev.to/cmilam/8-places-aws-bills-hide-money-that-nobodys-watching-4do5</guid>
      <description>&lt;p&gt;Every AWS account I've audited has real, findable waste in the same handful of places. Nothing exotic. Boring, structural waste that piles up because nobody seems to notice it.&lt;/p&gt;

&lt;p&gt;Here's the checklist I actually use, roughly in order of dollar impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Compute
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Idle or oversized EC2 instances. CloudWatch CPU/memory utilization under 10-15% sustained for two-plus weeks is your signal. AWS Compute Optimizer (free, opt-in) will do this analysis for you if you haven't turned it on yet.&lt;/li&gt;
&lt;li&gt;Stopped-but-not-terminated instances. A stopped instance still bills for any attached EBS volume. "Stopped" is not "free."&lt;/li&gt;
&lt;li&gt;Graviton migration. M6g/C6g instances typically run 10-20% cheaper than M5/C5 for compatible workloads, same performance.&lt;/li&gt;
&lt;li&gt;Dev/test running 24/7. Scheduling non-prod off nights and weekends is roughly a 65% runtime reduction for zero functional cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Storage
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unattached EBS volumes. &lt;code&gt;State = available&lt;/code&gt; volumes billed with nothing attached to them, extremely common after instance termination when "delete on termination" wasn't set.&lt;/li&gt;
&lt;li&gt;gp2 to gp3. About 20% cheaper at the same baseline performance. Same-day, zero-downtime conversion. There's rarely a reason not to do this immediately.&lt;/li&gt;
&lt;li&gt;S3 storage-class mismatches. Data sitting in Standard that's rarely accessed should be in Standard-IA, Glacier, or Glacier Deep Archive.&lt;/li&gt;
&lt;li&gt;Missing lifecycle policies. Buckets with no lifecycle rule at all: logs, backups, uploads that should be auto-transitioning or expiring and aren't.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Networking
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NAT Gateway cost. Bills per-hour and per-GB processed. Check whether VPC Endpoints (S3/DynamoDB Gateway endpoints are free) can take some of that traffic off it.&lt;/li&gt;
&lt;li&gt;Unused Elastic IPs. Billed hourly whether they're attached to anything or not.&lt;/li&gt;
&lt;li&gt;Idle load balancers. ALBs/NLBs with no healthy targets or near-zero traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Database
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Oversized RDS instances. Same CPU/memory review as EC2.&lt;/li&gt;
&lt;li&gt;Idle non-prod databases running 24/7.&lt;/li&gt;
&lt;li&gt;Multi-AZ on non-prod. Doubles cost, so confirm it's only turned on where it's actually needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Commitment discounts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RI/Savings Plan coverage at 0% on steady-state workloads means you're paying full on-demand rate for predictable usage. Check Cost Explorer's coverage report.&lt;/li&gt;
&lt;li&gt;Utilization matters too, not just coverage. Commitments you've already bought but aren't fully using are wasted money in the other direction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Serverless
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Over-provisioned Lambda memory. Cost scales with memory times duration.&lt;/li&gt;
&lt;li&gt;Unused provisioned concurrency. Bills whether it's invoked or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Logging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch Log Groups set to "Never Expire." That's the default. Nobody changes it. It quietly racks up cost forever until someone notices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Governance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Missing cost-allocation tags. If you can't attribute spend to a team, you can't hold anyone accountable for it.&lt;/li&gt;
&lt;li&gt;No budget alarms. Overspend gets discovered at month-end instead of in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of these is checkable by hand. If you'd rather not click through Cost Explorer and the EC2/S3/CloudWatch consoles yourself, I built a script that automates the API-checkable parts of this list: unattached volumes, unused EIPs, RI coverage, S3 lifecycle gaps, log retention. It's part of the &lt;a href="https://cmilam.gumroad.com/l/aws-cost-audit-kit" rel="noopener noreferrer"&gt;AWS Cost Audit Kit on Gumroad&lt;/a&gt;. I've run it against multiple real AWS accounts before shipping it, and the first account run found 11 buckets with no lifecycle policy and 29 log groups set to never expire.&lt;/p&gt;

&lt;p&gt;But the checklist above is the actually useful part, and it's free right here. Use it however you want.&lt;/p&gt;

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