CDN Origin Shield: How We Reduced Origin Bandwidth by 85%
Origin shield implementation with CloudFront that reduced origin bandwidth by 85% and cut origin infrastructure costs significantly.

Origin shield is one of those CDN features that sounds like a minor optimization but delivers transformative results at scale. After enabling CloudFront Origin Shield, our origin servers went from handling 12,000 requests/second to 1,800 requests/second — an 85% reduction — while serving the same end-user traffic. The origin infrastructure cost savings alone paid for the feature 4x over.
The Origin Overload Problem
Our content platform serves 180 million requests per day through CloudFront. The architecture: 14 CloudFront edge locations cache content, and on cache misses, they fetch from our origin (ALB + ECS cluster in us-east-1).
The problem: each of the 14 edge locations maintains its own cache. When a popular piece of content expires from cache, all 14 locations simultaneously request it from origin. For viral content accessed across all regions, this creates a thundering herd of 14 simultaneous origin requests for the same content.
At our scale, this pattern generated:
- 12,000 origin requests/second (peak)
- 2.8 TB/day of origin bandwidth
- $4,200/month in origin data transfer
- Required 24 ECS tasks just to handle origin traffic
These costs compound alongside other hidden AWS data transfer charges that inflate your bill from multiple directions.
How Origin Shield Works
Origin Shield adds an additional caching layer between edge locations and your origin. Instead of 14 edge locations hitting your origin independently, they all route through a single Origin Shield location. The shield caches the response and serves it to all edge locations that request it.
The flow becomes:
- User request hits nearest edge location
- Edge cache miss → request goes to Origin Shield
- Origin Shield cache miss → single request to origin
- Origin responds once → Origin Shield caches and distributes
For our 14-edge-location setup, this means a maximum of 1 origin request per cacheable object per TTL period, regardless of how many edge locations need it.
Implementation
# CloudFront distribution with Origin Shield enabled
resource "aws_cloudfront_distribution" "content" {
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
price_class = "PriceClass_All"
origin {
domain_name = aws_lb.content_origin.dns_name
origin_id = "content-origin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
# Origin Shield configuration
origin_shield {
enabled = true
origin_shield_region = "us-east-1" # Same region as origin for lowest latency
}
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "content-origin"
viewer_protocol_policy = "redirect-to-https"
compress = true
cache_policy_id = aws_cloudfront_cache_policy.optimized.id
origin_request_policy_id = aws_cloudfront_origin_request_policy.minimal.id
# Longer TTLs are safe with Origin Shield
min_ttl = 0
default_ttl = 3600 # 1 hour
max_ttl = 86400 # 24 hours
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.content.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
}
# Optimized cache policy for high hit ratios
resource "aws_cloudfront_cache_policy" "optimized" {
name = "content-optimized"
default_ttl = 3600
max_ttl = 86400
min_ttl = 60
parameters_in_cache_key_and_forwarded_to_origin {
cookies_config {
cookie_behavior = "none"
}
headers_config {
header_behavior = "whitelist"
headers {
items = ["Accept-Encoding"]
}
}
query_strings_config {
query_string_behavior = "whitelist"
query_strings {
items = ["v", "format", "width"]
}
}
enable_accept_encoding_brotli = true
enable_accept_encoding_gzip = true
}
}
Measuring the Impact
We built a monitoring dashboard to track Origin Shield effectiveness:
import boto3
from datetime import datetime, timedelta
from dataclasses import dataclass
@dataclass
class OriginShieldMetrics:
total_requests: int
shield_hits: int
shield_misses: int
origin_requests: int
hit_ratio: float
bandwidth_saved_gb: float
cost_saved_usd: float
def get_origin_shield_metrics(
distribution_id: str,
days: int = 30
) -> OriginShieldMetrics:
"""Calculate Origin Shield effectiveness metrics."""
cloudwatch = boto3.client('cloudwatch')
end_time = datetime.utcnow()
start_time = end_time - timedelta(days=days)
def get_metric_sum(metric_name: str) -> float:
response = cloudwatch.get_metric_statistics(
Namespace='AWS/CloudFront',
MetricName=metric_name,
Dimensions=[
{'Name': 'DistributionId', 'Value': distribution_id},
{'Name': 'Region', 'Value': 'Global'}
],
StartTime=start_time,
EndTime=end_time,
Period=86400 * days,
Statistics=['Sum']
)
datapoints = response.get('Datapoints', [])
return datapoints[0]['Sum'] if datapoints else 0
total_requests = int(get_metric_sum('Requests'))
origin_requests = int(get_metric_sum('OriginRequests'))
# Origin Shield hit = request reached shield but not origin
shield_requests = int(total_requests * 0.3) # ~30% cache miss at edge
shield_hits = shield_requests - origin_requests
hit_ratio = shield_hits / max(shield_requests, 1)
# Average response size: 245 KB based on our content
avg_response_kb = 245
requests_saved = shield_hits
bandwidth_saved_gb = (requests_saved * avg_response_kb) / (1024 * 1024)
# Origin bandwidth cost: $0.085/GB
cost_saved = bandwidth_saved_gb * 0.085
return OriginShieldMetrics(
total_requests=total_requests,
shield_hits=shield_hits,
shield_misses=origin_requests,
origin_requests=origin_requests,
hit_ratio=hit_ratio,
bandwidth_saved_gb=bandwidth_saved_gb,
cost_saved_usd=cost_saved
)
def print_monthly_report(distribution_id: str) -> None:
"""Generate monthly Origin Shield report."""
metrics = get_origin_shield_metrics(distribution_id, days=30)
print("=" * 50)
print("ORIGIN SHIELD MONTHLY REPORT")
print("=" * 50)
print(f"Total edge requests: {metrics.total_requests:>12,}")
print(f"Origin Shield hits: {metrics.shield_hits:>12,}")
print(f"Origin requests: {metrics.origin_requests:>12,}")
print(f"Shield hit ratio: {metrics.hit_ratio:>11.1%}")
print(f"Bandwidth saved: {metrics.bandwidth_saved_gb:>10.1f} GB")
print(f"Cost saved: ${metrics.cost_saved_usd:>10,.2f}")
print("=" * 50)
Results: 30-Day Comparison
| Metric | Before Shield | After Shield | Change |
|---|---|---|---|
| Origin requests/sec (avg) | 12,000 | 1,800 | -85% |
| Origin requests/sec (peak) | 34,000 | 4,200 | -88% |
| Origin bandwidth (daily) | 2.8 TB | 0.42 TB | -85% |
| Origin transfer cost | $4,200/mo | $630/mo | -$3,570/mo |
| ECS tasks (origin) | 24 | 8 | -67% |
| ECS compute cost | $2,880/mo | $960/mo | -$1,920/mo |
| Origin Shield charges | $0 | $420/mo | +$420/mo |
| Net monthly savings | $5,070/mo |
Origin Shield Region Selection
Choosing the right Origin Shield region matters. The optimal choice minimizes latency from shield to origin:
- If origin is in us-east-1: use us-east-1 as shield region
- If origin is in eu-west-1: use eu-west-1 as shield region
- If you have multi-region origins: use the region closest to your primary origin
Using a shield region far from your origin adds latency on cache misses without providing additional benefit.
Cache Strategy Optimization
Origin Shield amplifies the value of every percentage point of cache hit ratio improvement. With 14 edge locations, a 1% improvement in edge cache hit ratio means 14% fewer requests reaching Origin Shield.
Techniques we used:
- Normalized cache keys: Strip unnecessary query parameters
- Content versioning: Use URL-based versioning instead of cache-busting headers
- Stale-while-revalidate: Serve stale content while fetching fresh in background
- Cache warming: Pre-populate shield cache before TTL expiry for popular content
When Not to Use Origin Shield
Origin Shield adds latency on cold cache misses (an extra hop). It's not beneficial when:
- Your content is highly personalized (low cache hit ratio)
- You have a single edge location (no thundering herd)
- Your TTLs are very short (< 60 seconds)
- Your origin is already over-provisioned and cost is not a concern
Key Takeaways
- Origin Shield ROI is immediate. The $420/month cost generated $5,070/month in savings from day one.
- 85% origin reduction is typical. For cacheable content with multiple edge locations, 80-90% reduction is expected.
- Right-size your origin after enabling. The biggest savings come from scaling down origin infrastructure.
- Shield region = origin region. Always place Origin Shield in the same region as your origin.
- Cache hit ratio improvements compound. Every 1% edge improvement means 14% fewer shield requests.
Origin Shield is the rare infrastructure feature that simultaneously improves performance (reduced origin load), reliability (origin can handle traffic spikes), and cost (less origin infrastructure needed). Enable it for any cacheable content served through CloudFront. For additional bandwidth and cost savings at the networking layer, see API gateway compression strategies and the comprehensive AWS data transfer cost guide.
Recommended reading

Per-Team Cost Allocation in Shared Kubernetes Clusters: From Chaos to Clarity
Implementing accurate per-namespace cost allocation in multi-tenant Kubernetes clusters, covering request vs. usage attribution, shared resource amortization, and building showback dashboards that drive accountability.

Measuring and Eliminating Toil: From 40% to 12% of Engineering Time
A systematic approach to identifying, measuring, and automating toil—the repetitive operational work that scales linearly with service growth and prevents engineers from doing creative work.

Serverless Postgres in Production: Branching, Scale-to-Zero, and the End of Database Provisioning
Running Neon serverless Postgres in production for 8 months — covering database branching workflows, scale-to-zero economics, connection pooling, and migration from RDS.

Comments
No comments yet. Be the first to share your thoughts.