There was a time when I thought a fast server meant a fast site. But I was wrong. No matter how optimized my code was, users from Europe or Asia were seeing slow load times. Meanwhile, everything loaded fine for me—because my server was in the same country. So I started digging. That’s when I found the real bottleneck: distance. distance. The solution? AWS CloudFront. AWS CloudFront. It didn’t just improve my load times—it cut them in half for users worldwide. Here’s exactly how I did it. Step 1: Understanding the Problem My site was hosted on an EC2 instance in Virginia (us-east-1). Great performance in the US. Terrible everywhere else. When a visitor in Germany loaded my homepage, the request had to travel across the ocean. It wasn’t the server—it was the trip. Even with gzip, cache control, and image optimization, I was still losing 2–4 seconds on initial page load. Not ideal if you care about bounce rate. Step 2: What Is CloudFront? CloudFront is AWS’s Content Delivery Network (CDN). It distributes your static (and even dynamic) content across 300+ edge locations around the world. When a user visits your site, CloudFront serves content from the nearest edge server, not your origin server. nearest edge server That means fewer miles traveled, faster response times. It also caches content intelligently, reducing backend load. Perfect for image-heavy websites, SPAs, or any site that serves repeat traffic. Step 3: Preparing My Content for CloudFront Before using CloudFront, I made sure my site had: Static assets stored on S3 (images, CSS, JS) HTML files deployed via S3 (my site was static, but this works with EC2 or other backends too) Correct Content-Type headers on files (important for caching) Proper Cache-Control metadata set on S3 objects (so CloudFront knows what to cache and for how long) Static assets stored on S3 (images, CSS, JS) Static assets HTML files deployed via S3 (my site was static, but this works with EC2 or other backends too) HTML files Correct Content-Type headers on files (important for caching) Content-Type Proper Cache-Control metadata set on S3 objects (so CloudFront knows what to cache and for how long) Cache-Control Without these, CloudFront would still work—but not well. Bad headers = no cache = no performance win. Step 4: Creating a CloudFront Distribution Here’s exactly how I set it up: Opened AWS Console > CloudFront Clicked “Create Distribution” Under Origin Domain, I selected my S3 bucket (the one hosting my site) Left Origin Path empty (since I wanted to serve the whole bucket) Set Viewer Protocol Policy to “Redirect HTTP to HTTPS” Under Default Cache Behavior, I enabled: Caching based on headers: None (to improve cache hits) Compress objects automatically: Yes For Price Class, I chose “Use all edge locations” for maximum global reach Opened AWS Console > CloudFront Opened AWS Console > CloudFront Clicked “Create Distribution” “Create Distribution” Under Origin Domain, I selected my S3 bucket (the one hosting my site) Origin Domain Left Origin Path empty (since I wanted to serve the whole bucket) Origin Path Set Viewer Protocol Policy to “Redirect HTTP to HTTPS” Viewer Protocol Policy Under Default Cache Behavior, I enabled: Caching based on headers: None (to improve cache hits) Compress objects automatically: Yes Default Cache Behavior Caching based on headers: None (to improve cache hits) Compress objects automatically: Yes Caching based on headers: None (to improve cache hits) Caching based on headers Compress objects automatically: Yes Compress objects automatically For Price Class, I chose “Use all edge locations” for maximum global reach Price Class Lastly, I created the distribution. It took about 15 minutes to deploy. Step 5: Connecting My Domain CloudFront gives you a default domain like d1234.cloudfront.net. d1234.cloudfront.net Not great for production. To use my custom domain (www.mysite.com): www.mysite.com I went to Route 53 (or your DNS provider) Created a CNAME record pointing www.mysite.com to my CloudFront domain In CloudFront, under Alternate Domain Names (CNAMEs), I added www.mysite.com Set up an SSL certificate in ACM (Amazon Certificate Manager) for my domain Linked it in the CloudFront distribution I went to Route 53 (or your DNS provider) Route 53 Created a CNAME record pointing www.mysite.com to my CloudFront domain CNAME www.mysite.com In CloudFront, under Alternate Domain Names (CNAMEs), I added www.mysite.com Alternate Domain Names (CNAMEs) www.mysite.com Set up an SSL certificate in ACM (Amazon Certificate Manager) for my domain SSL certificate Linked it in the CloudFront distribution After that, my domain worked through CloudFront—securely, globally, and fast. Step 6: Measuring the Results I didn’t just want to “feel” the difference. I wanted proof. So I ran tests using: Google PageSpeed Insights WebPageTest.org (with servers in Asia and Europe) Lighthouse in Chrome DevTools Google PageSpeed Insights Google PageSpeed Insights WebPageTest.org (with servers in Asia and Europe) WebPageTest.org WebPageTest.org Lighthouse in Chrome DevTools Lighthouse in Chrome DevTools Before CloudFront (Germany test server): Time to First Byte (TTFB): ~900ms Full load: ~3.5 seconds Time to First Byte (TTFB): ~900ms Full load: ~3.5 seconds After CloudFront: TTFB: ~200ms Full load: ~1.6 seconds TTFB: ~200ms Full load: ~1.6 seconds That’s more than 2x faster. And in some regions, it was even faster than that. Step 7: Fine-Tuning the Cache Behavior After a week, I noticed some files weren’t updating as expected. Turns out I had set a long cache duration on JavaScript files. long cache duration To fix this, I: Updated S3 object metadata to use Cache-Control: max-age=3600, must-revalidate In CloudFront, created cache behaviors to set different rules for: /index.html → short cache (1 minute) /static/* → long cache (1 month) Enabled Invalidations when I pushed updates (can be done via CLI too) Updated S3 object metadata to use Cache-Control: max-age=3600, must-revalidate Cache-Control: max-age=3600, must-revalidate In CloudFront, created cache behaviors to set different rules for: /index.html → short cache (1 minute) /static/* → long cache (1 month) cache behaviors /index.html → short cache (1 minute) /static/* → long cache (1 month) /index.html → short cache (1 minute) /index.html /static/* → long cache (1 month) /static/* Enabled Invalidations when I pushed updates (can be done via CLI too) Invalidations This gave me the best of both worlds: Fast caching + flexibility to update content when needed. What You Should Know Before Using CloudFront Here are a few simple lessons I learned: Use S3 + CloudFront if you’re serving a static site. It’s cheap and reliable. Always configure headers. Without correct Content-Type and Cache-Control, performance gains drop. CloudFront logs are a goldmine. Use them to see where your traffic comes from and what’s being cached. Invalidate carefully. CloudFront invalidation is powerful, but avoid frequent full-path invalidations—they cost money and time. Price class matters. If your traffic is mostly in one region, use a regional edge setting to reduce costs. Use S3 + CloudFront if you’re serving a static site. It’s cheap and reliable. Use S3 + CloudFront Always configure headers. Without correct Content-Type and Cache-Control, performance gains drop. Always configure headers Content-Type Cache-Control CloudFront logs are a goldmine. Use them to see where your traffic comes from and what’s being cached. CloudFront logs Invalidate carefully. CloudFront invalidation is powerful, but avoid frequent full-path invalidations—they cost money and time. Invalidate carefully Price class matters. If your traffic is mostly in one region, use a regional edge setting to reduce costs. Price class matters Final Thoughts You don’t need a complex backend to go global. You don’t need 10 engineers or a $10K/month CDN. What you need is a clear understanding of where your performance is breaking—and a simple tool to fix it. For me, that was AWS CloudFront. It let me serve my site faster, everywhere, without changing a single line of code. The results were real. The difference was visible. And the setup? Just a few clicks. If you’re running a public-facing site and haven’t used CloudFront yet, you’re leaving speed on the table.