Vibe Coder's Guide

The cheapest static site hosting in 2026: $0.50/month on AWS

April 13, 2026 · awsdeploymentinfrastructure

This site costs me $0.50 a month to run. It's served from AWS — S3 for the files, CloudFront for the CDN, Route 53 for DNS, ACM for the SSL cert. Total monthly bill: one Route 53 hosted zone fee. Everything else fits inside the AWS free tier so comfortably that I expect to never pay for it.

People assume AWS is expensive because the AWS console is intimidating. The console is intimidating. The bill is not. Here's exactly what I did.

The shape

GoDaddy (registrar)
   ↓ nameservers
Route 53 (DNS) — $0.50/month
   ↓ alias records
CloudFront (CDN) — free tier (1TB out, 10M req/month)
   ↓ OAC-signed reads
S3 bucket (private) — pennies/month for <1MB site
   ↑
ACM cert (us-east-1) — always free

Five services. Each does one thing. Together they serve a static site at any scale you'll realistically hit.

Step by step

1. Buy the domain wherever you want. I used GoDaddy because that's the skill bundle's recommendation. Cloudflare Registrar is cheaper at renewal but only sells some TLDs.

2. Create a Route 53 hosted zone for the domain. AWS gives you four nameservers like ns-1255.awsdns-28.org. Paste those into your registrar's "custom nameservers" field. From now on Route 53 owns DNS for the domain.

3. Request an ACM certificate. It must be in us-east-1 for CloudFront to use it. Request both apex (example.com) and www.example.com. Validation method: DNS. ACM gives you two CNAME records — drop them into Route 53. Five minutes later the cert says "Issued."

4. Create an S3 bucket named after your project. Block all public access. Set ownership to BucketOwnerEnforced. This bucket is private — CloudFront reads from it through Origin Access Control, but the public can't.

5. Create the CloudFront distribution. Origin: the S3 bucket, signed via OAC. Aliases: your apex + www. Viewer cert: the ACM cert. Default root object: index.html. Custom error responses: 403 → /index.html (200), 404 → /index.html (200) — this is what makes SPA routing work.

6. Attach the OAC bucket policy to the S3 bucket so CloudFront can read it.

7. Create A and AAAA alias records in Route 53 for the apex and www, both pointing at the CloudFront distribution. Use the magic hosted-zone ID Z2FDTNDATAQYW2 — that's the universal CloudFront alias zone.

8. Build and deploy. Three steps:

npm run build
aws s3 sync dist/ s3://your-bucket/ --delete \
  --cache-control "public, max-age=31536000, immutable"
aws cloudfront create-invalidation \
  --distribution-id E1234XYZ --paths "/*"

That's the whole thing. About 30 minutes the first time, 30 seconds for every subsequent deploy.

The cost math

Route 53 hosted zone: $0.50/month flat. This is the only line item I ever pay.

CloudFront: free tier covers 1 TB of egress and 10 million HTTPS requests per month. A static site like this one — a single page, 250KB of compressed assets — would need about 4 million unique visitors a month to push the egress past free tier. I expect to hit zero of that.

S3: storage at $0.023/GB-month. The whole site is under 1 MB. Storage cost rounds to $0.00002/month.

ACM certificates: always free. There's no upgrade tier.

Total predictable monthly bill: $0.50. I have run this exact stack on three projects for a combined four years and have paid AWS less in total than I'd pay Vercel for a single month at their Pro tier.

Why this is better than Vercel for static sites

Vercel is wonderful. It's the right answer when you're shipping a Next.js app with API routes, ISR, image optimization, and 50 different environment variables. The convenience is worth $20–$50 a month if your app actually uses what you're paying for.

This site does none of that. It's a Vite SPA with two zip downloads. Vercel for this would be paying for power I'm not using. AWS at this scale is paying for nothing because the free tiers absorb it all.

The trade-off is convenience: there's no git push → auto-deploy. I run a 12-line shell script. For a static site that I deploy manually a few times a week, that's fine. For an active app with multiple developers, it would be friction worth eliminating.

When this stops working

The pattern breaks down when you need a backend. CloudFront is a CDN; it doesn't run server-side code. If your app needs server functions, you're either adding Lambda + API Gateway (still cheap, but more setup), moving to Vercel/Netlify functions, or running a tiny server somewhere.

For a static site, though — landing pages, docs, marketing sites, blogs, downloadable artifacts — there is no cheaper or more reliable pattern. The internet runs on this. Your site can too.

If you want the deploy script I use here, it's in this site's scripts/deploy.sh and I'll publish a cleaner generic version soon. The whole thing is 50 lines.


← All posts