
My EC2 Crashed After 10k Requests. I Put CloudFront in Front, and It Now Handles 1M Requests for $1
My t3.micro died when my blog post went viral. I fixed it without upgrading EC2. I put CloudFront in front with 1-day caching. Origin load dropped 94%, and my bill dropped too.
The Day My Blog Went Viral (And My EC2 Died)
I posted my project on Reddit. 10k users in 1 hour.
I posted my project on Reddit. 10k users in 1 hour.
My single EC2: CPU 100%, Apache timed out, 502 errors everywhere. I was losing every new user.
I didn’t need a bigger server. I needed to stop hitting the server.
The Fix: CloudFront as a Shield
Before: 10k Users -> EC2 (EC2 does all work)
After: 10k Users -> CloudFront Edge (400+ locations) -> EC2 (only when cache misses)
Before: 10k Users -> EC2 (EC2 does all work)
After: 10k Users -> CloudFront Edge (400+ locations) -> EC2 (only when cache misses)
Static files, images, even my API response for 1 hour — all served from Edge, not my EC2.
How I Set It Up in 10 Minutes
Step 1: Create Distribution
CloudFront > Create Distribution:
Step 1: Create Distribution
CloudFront > Create Distribution:
Origin Domain: Your ALB/EC2 DNS (e.g. my-alb-123.ap-south-1.elb.amazonaws.com)
Viewer Protocol: Redirect HTTP to HTTPS
This is the money saver: Cache Policy = CachingOptimized, Origin Request Policy = AllViewer (if you need headers)
Step 2: Cache Behavior That Actually Saves Money
For /static/, /images/:
Viewer Protocol: Redirect HTTP to HTTPS
This is the money saver: Cache Policy = CachingOptimized, Origin Request Policy = AllViewer (if you need headers)
Step 2: Cache Behavior That Actually Saves Money
For /static/, /images/:
TTL: 1 day (86400s)
Compress objects: Yes
For /api/* (if your API is cacheable):
Compress objects: Yes
For /api/* (if your API is cacheable):
TTL: 1 hour. Add header Cache-Control: public, max-age=3600 from your EC2.
Step 3: Point Your Domain
Route 53 > Your domain > A record Alias to CloudFront distribution.
Step 3: Point Your Domain
Route 53 > Your domain > A record Alias to CloudFront distribution.
Done. No code change.
The Result
Load test with hey -n 100000 -c 100:
Load test with hey -n 100000 -c 100:
Before CloudFront: EC2 CPU 98%, 42% failed requests
After CloudFront: EC2 CPU 7%, 0% failed, Cache Hit Ratio: 94%
Cost: 1M requests via CloudFront = ∼$1.10. Same 1M to EC2 via ALB would have needed bigger instances + data transfer = ∼$18.
After CloudFront: EC2 CPU 7%, 0% failed, Cache Hit Ratio: 94%
Cost: 1M requests via CloudFront = ∼$1.10. Same 1M to EC2 via ALB would have needed bigger instances + data transfer = ∼$18.
Plus, my users in US/EU now load in 45ms instead of 350ms.
2 Mistakes to Avoid
Forgetting invalidation: After you update your site, run Create Invalidation: /* — otherwise users see old version.
Caching dynamic stuff: Don't cache /login or /cart. Set Behavior Path Pattern to exclude them.
Forgetting invalidation: After you update your site, run Create Invalidation: /* — otherwise users see old version.
Caching dynamic stuff: Don't cache /login or /cart. Set Behavior Path Pattern to exclude them.
Built and tested on my own account. No secrets or account IDs shared. If you are still serving static files directly from EC2, try this once — hit Like if you want my Terraform for CloudFront + S3 + EC2 setup.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article