How to Reduce S3 Bandwidth Costs by Integrating CloudFlare CDN with AWS S3 Bucket


2 views

When serving thousands of media assets (JPGs, PNGs, etc.) directly from a public Amazon S3 bucket, bandwidth costs can quickly escalate. The standard S3 endpoint (https://my-bucket.s3.us-east-1.amazonaws.com) serves files directly without caching, meaning every request hits S3 infrastructure and incurs data transfer fees.

CloudFlare can cache these assets at their edge locations, significantly reducing:

  • Direct S3 bandwidth consumption (up to 90% reduction)
  • Latency for end users
  • Origin server load

Contrary to common setups, you don't need to migrate your entire DNS to CloudFlare. Here's how to proxy only your S3 traffic:

  1. Create a CNAME record in your existing DNS pointing to your S3 endpoint:
    assets.yourdomain.com CNAME my-bucket.s3.us-east-1.amazonaws.com
  2. In CloudFlare DNS settings, add the same record but enable the orange cloud proxy icon
  3. Configure CloudFlare caching rules:
    // Page Rule example
    *.yourdomain.com/*
    Cache Level: Cache Everything
    Edge Cache TTL: 1 month
    Browser Cache TTL: 1 week

Ensure your bucket policy allows access from both direct S3 URLs and your CloudFlare domain:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "StringLike": {
          "aws:Referer": [
            "https://assets.yourdomain.com/*",
            "https://my-bucket.s3.us-east-1.amazonaws.com/*"
          ]
        }
      }
    }
  ]
}

Verify the setup works by:

  • Checking CloudFlare cache status headers (CF-Cache-Status: HIT)
  • Monitoring S3 bandwidth metrics before/after implementation
  • Using curl to test cache behavior:
    curl -I https://assets.yourdomain.com/path/to/image.jpg

For maximum savings:

  1. Implement CloudFlare Workers for cache key normalization
  2. Set up S3 lifecycle policies for infrequently accessed objects
  3. Enable CloudFlare Argo Smart Routing for better performance

Many developers face unexpectedly high AWS bills when using public S3 buckets to serve media assets. The standard S3 endpoint (https://[bucket].s3.[region].amazonaws.com) charges for both storage AND data transfer - and those egress fees add up quickly when serving thousands of images to forum users.

While CloudFlare is a great CDN, AWS CloudFront integrates natively with S3 and provides:

  • Lower bandwidth costs (CloudFront egress rates are ~50% cheaper than S3)
  • Built-in caching at edge locations
  • No DNS changes required for your main domain
  • Seamless HTTPS without certificate management

Here's how to set it up without disrupting your existing infrastructure:


# 1. Create CloudFront distribution
aws cloudfront create-distribution \
    --origin-domain-name my-bucket.s3.us-east-1.amazonaws.com \
    --default-root-object "" \
    --enabled \
    --price-class PriceClass_100

Configure the origin with these settings:

  • Origin Domain: Select your S3 bucket from dropdown
  • Restrict Bucket Access: Yes (creates Origin Access Identity)
  • Grant Permissions: Yes (auto-updates bucket policy)

Add this cache policy to maximize cache hits:


# Cache policy JSON
{
  "Comment": "S3 image caching",
  "DefaultTTL": 86400,
  "MaxTTL": 604800,
  "ParametersInCacheKeyAndForwardedToOrigin": {
    "EnableAcceptEncodingGzip": true,
    "Headers": {
      "Quantity": 0
    },
    "Cookies": {
      "Quantity": 0
    },
    "QueryStrings": {
      "Quantity": 0
    }
  }
}

Update your forum software to use the new CloudFront domain:


// PHP example for forum software
function convert_s3_to_cdn($url) {
    return str_replace(
        'https://my-bucket.s3.us-east-1.amazonaws.com',
        'https://d111111abcdef8.cloudfront.net',
        $url
    );
}

Based on serving 50TB/month of images:

Solution Bandwidth Cost
Direct S3 $4,250
CloudFront $2,125