Ask

woke up to a $1,940 aws bill on a hobby project, where do i even look

Do not turn anything off yet. First find out what it is - it takes about five minutes and guessing costs you more.

Cost Explorer, then set it up like this:

  • date range: last 30 days
  • granularity: daily
  • group by: Usage Type (not Service - Service will tell you "EC2-Other" and you will learn nothing)

The daily view is the important part. You are looking for the day the line goes up, because that tells you what you changed. Usage Type tells you what you are being charged for in words specific enough to search.

On a small account, the top three causes by a mile:

  1. NAT Gateway data processing. Charged per GB through it plus an hourly rate. If your VPC tutorial put your compute in a private subnet with a NAT gateway, then every byte your hourly job pulls from S3 goes through it and gets billed. Same-region S3 traffic that should be free suddenly costs $0.045 a gigabyte. This is the single most common way a hobby account produces a four figure bill, and your description - private subnet, hourly job, S3 - matches it exactly.
  2. Cross-AZ data transfer. Chatty services in different availability zones, billed both directions.
  3. EBS snapshots or forgotten volumes left behind by an instance you terminated.

If it is number one, the fix is a VPC gateway endpoint for S3. It is free, it takes about two minutes in the console, and it routes S3 traffic inside your VPC instead of out through the NAT. Add one for DynamoDB too while you are there.

Be aware that interface endpoints for other services are not free - they have an hourly charge per AZ plus per GB. The gateway endpoints for S3 and DynamoDB are the free ones. Do not read "endpoints are free" and add fifteen of them.

138 · in/cloud-bill-shock ·

r2 bill hit $214 from class a operations because i list the bucket per request

The mental model that fixes this permanently: object storage is a place to put bytes, not a place to ask questions. Any question - what exists, what changed, what belongs to this user - is a database query.

What that looks like concretely:

  • one row per object in D1 (or Postgres, whatever you have): key, size, content type, owner, created_at, plus whatever you want to filter on.
  • writes go through your code, so you insert the row in the same request that does the PUT.
  • the gallery reads the DB. R2 is only ever touched to serve or store the actual bytes.
  • a nightly reconciliation job lists the bucket once and fixes drift, because drift will happen.

That nightly job is one Class A operation per 1,000 objects, once a day. Your 47 million becomes something like 3,000 a month.

The pricing asymmetry is the thing to burn into memory: Class A (writes and lists) costs more than ten times what Class B (reads) costs. Any design where a read path triggers a Class A op is going to be expensive, and it will be expensive in proportion to your traffic, which is exactly the wrong direction.

79 · in/cloud-bill-shock ·

neon compute never scaled to zero because a 30s health check kept the branch awake

Add to the list of things that quietly keep serverless databases awake:

  • migration tooling that opens an advisory-lock connection at boot and holds it
  • a background job runner polling a jobs table every few seconds
  • an admin dashboard tab someone left open with a 10 second refresh
  • log shippers or metrics exporters querying pg_stat_*
  • your own local development environment connected to production because of a stale .env

The last one has happened to two people I know and the tell is compute activity in a timezone where you have no users.

48 · in/cloud-bill-shock ·

r2 or s3+cloudfront for 8 tb a month of egress on a $400 budget

At 8TB and growing 15% a month, move. Zero egress is not a marginal saving at your volume, it is the difference between a viable product and one where every new customer makes the maths worse.

Rough monthly egress at list price for 8,000GB:

  • S3 straight to the internet: around $711
  • S3 behind CloudFront: around $595 after the free tier
  • R2: $0

You pay storage on R2 either way - 600GB is roughly $9 - plus operations, which for video streaming are Class B and negligible. So your $400 budget goes from impossible to mostly unspent.

The honest reasons not to move:

  • You need S3 event notifications into an existing AWS pipeline. Your thumbnail Lambda is exactly this. R2 has event notifications too, but they land in a different queue system and you would rewrite that piece.
  • Lifecycle rules into archival storage classes, if you have a lot of cold content.
  • Any AWS-native feature applied on the object path.

Given you have exactly one Lambda hook, rewriting it is a day of work against $600 a month. That is not a close call.

One genuinely important detail: the zero-egress model assumes normal serving. Read the terms for your traffic type rather than assuming, and if you are ever unsure whether your usage fits, ask them before you migrate 600GB.

83 · in/cloud-bill-shock ·