AWS CloudFront cost optimization is not a coupon. It is cache behavior, origin path, and price class — three levers CFOs feel because they show up as line items next to data transfer. Mid-market teams often treat CloudFront as "the CDN checkbox for SOC 2 encryption in transit" and never look at the bill until a product launch, a bad Cache-Control header, or a video asset turns origin fetches into a second compute bill.
Rutagon runs a two-week cost diagnostic that starts with Cost Explorer and CloudFront access logs, not a slide about "right-sizing the internet." We have done this on a production SaaS platform and a content platform that is 100 percent Terraform-managed. The patterns repeat.
The Three Levers That Move a CloudFront Bill
AWS prices CloudFront on HTTP/HTTPS requests, data transfer out to the internet by region, and a handful of add-ons (invalidations beyond the free tier, real-time logs, Origin Shield, extra certificates). Public pricing is documented in the CloudFront Developer Guide and the service pricing page. The important operational fact: price class lets you serve from a subset of edge locations. Price Class 100 uses only North America and Europe. Price Class 200 adds several other regions. Price Class All uses the full network. If your buyers are not on every continent, All is a silent markup.
The second lever is cache hit ratio. Misses become origin requests. Origin requests become data transfer from the origin and origin compute — S3 GET charges, ALB/ECS/Lambda work, and sometimes a NAT gateway tax if the origin path is sloppy. A hit ratio that looks "fine" at 70 percent can still dominate the bill if the 30 percent miss traffic is large objects.
The third lever is Origin Shield. Shield is a regional cache in front of the origin. It costs extra per request in the Shield region, and it pays for itself when many edges would otherwise stampede the origin on the same object. AWS documents Shield as an incremental cache layer, not magic (Origin Shield).
AWS CloudFront Cost Optimization We Measure First
Before anyone changes a distribution, we pull:
- Cost Explorer by usage type (
US-Requests-Tier1,EU-DataTransfer-Out-Bytes, Shield, invalidations). - Cache statistics from CloudWatch (
Requests,BytesDownloaded,CacheHitRate,OriginLatency). - A sampled access log:
cs-uri-stem,sc-bytes,x-edge-result-type,cs-method.
The first report is rude and useful. It names the paths that miss. It names the price class. It names whether you are paying for All because someone left the console default.
resource "aws_cloudfront_distribution" "web" {
enabled = true
price_class = "PriceClass_100" # North America + Europe only
origin {
domain_name = aws_s3_bucket.origin.bucket_regional_domain_name
origin_id = "s3-origin"
origin_shield {
enabled = true
origin_shield_region = "us-east-1"
}
}
default_cache_behavior {
target_origin_id = "s3-origin"
viewer_protocol_policy = "redirect-to-https"
compress = true
cache_policy_id = aws_cloudfront_cache_policy.static.id
}
}
Price Class 100 is a product decision, not a morality play. If you have a real APAC customer base, Class All (or 200) is correct. If you do not, you are donating margin to edge locations you never needed.
Cache Policy Mistakes That Look Like Traffic Growth
The expensive bugs are headers and query strings. A cache policy that forwards Authorization or an unbounded query string turns every personalized request into a miss. A legacy behavior that still uses the old forwarded-values block with "all headers" does the same.
We split behaviors:
- Immutable hashed assets (
/static/*) — long TTL, no cookies, no query strings. - HTML documents — short TTL or cache disabled if the app is fully personalized.
- API origins — usually not CloudFront-cached at all; if they are, cache keys are explicit.
Compression (compress = true) is free-ish and cuts transfer bytes. Brotli/gzip at the edge is one of the few "turn it on" wins left. Invalidations are the opposite: using /* as a deploy step is how teams blow the free invalidation path and still miss objects because the cache key was wrong.
This work sits next to VPC endpoint and NAT cost reduction when the origin is in a private subnet, and next to S3 storage class optimization when the origin bucket is also over-tiered. The capability page is AWS cloud infrastructure.
Origin Shield and the Stampede
Launches and cache flushes create a classic thundering herd: every edge misses at once and the origin scales or times out. Origin Shield collapses those misses to one regional cache. We enable it when:
- The origin is compute (ALB, ECS, Lambda URL), not a cheap S3 GET.
- Objects are popular enough that many edges share them.
- You already pay for a multi-region audience (otherwise Shield plus Class All is stacking costs).
We do not enable Shield on a tiny marketing site whose origin is S3 and whose hit ratio is already 95 percent. That is how FinOps theater starts.
Compliance Side Note, Not a Cert Claim
CloudFront often appears in SOC 2 narratives as the TLS termination and WAF attachment point. That is architecture, not a certification. Rutagon does not hold FedRAMP or SOC 2. We will still configure TLS policies, logging, and WAF association in a way that is easy to evidence — see AWS WAF and Shield architecture — but the cost article is about the bill.
On a content platform we inherited, moving hashed assets to a dedicated behavior and dropping Price Class All to 100 cut CloudFront spend by a third without touching application code. Your number will differ. The diagnostic is how we find it.
Talk through a two-week AWS cost diagnostic →
907-841-8407 · contact@rutagon.com
Frequently Asked Questions
Is CloudFront cheaper than putting the bucket in a public website hosting config?
Public website hosting on S3 has no CDN cache and a different (often worse) transfer profile once traffic leaves the region. CloudFront plus an origin access control is the usual production shape. Cost depends on hit ratio, not on the checkbox labeled CDN.
When does Origin Shield increase the bill?
When almost every request is already a hit, or when traffic is so sparse that the extra Shield request charge has nothing to collapse. We model Shield from access logs before turning it on.
Can we use CloudFront Functions instead of Lambda@Edge to save money?
For header rewrites and simple redirects, CloudFront Functions are priced for high-volume edge logic. Lambda@Edge is for heavier work. We pick the cheaper runtime that still meets the behavior, then measure.
Does price class affect SOC 2 or encryption?
No. Price class selects edge geography. TLS and logging are separate settings. Do not keep Price Class All as a security superstition.
How do you handle multi-brand or multi-environment distributions?
Separate distributions with shared cache policies in Terraform, distinct log prefixes, and tags that Cost Explorer can group. One mega-distribution with path spaghetti is how hit-ratio math becomes unreadable.