A client came to us in shock over their CloudFront bill — $1,500/month during their peak sales period. Here’s how we got it down to $200/month.

Hi everyone 👋

A client reached out to us after opening their AWS invoice during their busiest sales month of the year and seeing CloudFront alone hit ~$1,500/month, with the vast majority of that coming from data transfer out to their customers. They weren’t looking for a full re-architecture — they just wanted to know: is this normal, and can anything be done about it?

Their system had been running since the early 202x — a few years old at this point. Back then, Amazon CloudFront only had one pricing model: pay-as-you-go, billed per GB of data transferred out plus per-request fees. That’s just how it was when their system was built, so that’s what they built on, and it stayed that way ever since — nobody on their side had a reason to revisit it, until a peak-season invoice made the cost impossible to ignore.

We took the case and started digging the same day.

🤔 Why this had been quietly building up

A $1,500/month CDN bill isn’t necessarily alarming for a growing production system — but it’s the kind of number that’s easy to just accept and stop thinking about, especially on infrastructure nobody actively works on day to day. It only becomes a “shock” when a peak sales month makes it spike and someone finally looks at the invoice line by line.

The timing worked in the client’s favor, though: AWS had just announced something new — CloudFront flat-rate pricing plans — Free, Pro, Business, and Premium tiers, each bundling CDN + AWS WAF + DDoS protection + Route 53 DNS + CloudWatch Logs ingestion into one flat monthly price with no overage charges. Importantly, it applies to existing distributions, not just brand-new ones, with no annual commitment required.

That mattered a lot here, since the client’s distribution predated all of this by years.

❗ Why pay-as-you-go quietly punishes older setups

Pay-as-you-go is fine when traffic is small or unpredictable. But once a distribution has run for years with steady, high-volume traffic — and then hits a seasonal peak on top of that — a few things stack up against you:

  • You’re paying per GB, indefinitely, with no ceiling — the bigger the sales month, the bigger the bill, linearly, with no cap.
  • Nobody goes back to re-evaluate the pricing model after launch, because “it’s already running, don’t touch it” is a very natural instinct for infrastructure that just works.
  • The bill is really CloudFront + AWS WAF + Route 53 + CloudWatch, billed separately, so it’s not obvious how much is actually on the table until someone adds it all up — which is exactly what the client hadn’t done until the shock invoice.

🛠️ What we did, right away

Instead of proposing a big migration project, we treated it as a quick, measurable win: audit first, then act.

1️⃣ Pulled the client’s actual usage numbers

Before recommending anything, we pulled their real monthly numbers for data transfer and request count straight from CloudFront and Cost Explorer — including the peak-month spike, not just an average month. Each flat-rate tier publishes a monthly usage allowance (a soft baseline, not a hard cap):

PlanPrice/moData transferRequests
Free$0100 GB1 M
Pro$1550 TB10 M
Business$20050 TB125 M
Premiumfrom $1,000from 50 TB (configurable up to 600 TB)from 500 M (configurable up to 6 B)

Even counting their peak sales month, the client’s usage sat comfortably inside the Business tier’s 50 TB / 125 M-request allowance, with headroom to spare — so that’s what we recommended.

2️⃣ Checked for unsupported legacy features first

This is the part that actually took the most time. Flat-rate plans don’t support a handful of legacy CloudFront configurations, and a distribution running since 202x was a prime suspect for carrying some of these:

  • Origin Access Identity (OAI) → migrated to Origin Access Control (OAC).
  • Legacy ForwardedValues cache behavior config → migrated to cache policies + origin request policies.
  • Real-time access logs, if in use → fall back to standard access logs.
  • Dedicated IP/SSL, field-level encryption, IAM server certificates → none of these were in play here, thankfully.

We also had to make sure the distribution had an AWS WAF Web ACL attached, since that’s required to subscribe to a plan at all — conveniently, the Business tier already includes WAF at no extra cost, which was a nice side upgrade for the client’s security posture.

3️⃣ Switched the distribution and attached Route 53

Once the config was clean, switching an existing distribution to a plan is just a setting on the distribution (console, CLI, or the PricingPlanManager API) — no downtime, no new domain, no DNS cutover for the client’s end users. We also attached their Route 53 hosted zone to the plan, since Business covers the hosted zone fee and DNS queries too — as long as their records pointing at CloudFront use ALIAS, which don’t count against the DNS allowance at all.

4️⃣ Set up monitoring so the client never gets shocked again

One thing we made sure the client understood: the usage allowance isn’t a hard wall. AWS designed it to absorb normal spikes — a traffic spike up to 3x the monthly allowance in a given month doesn’t affect the account at all, and sustained overage is evaluated over 2-3 months before AWS adjusts anything (and even then, it’s a gradual traffic-shaping adjustment, not a surprise bill). We turned on the built-in usage notifications (50% / 80% / 100%) so the client gets an early heads-up long before their next peak season, instead of finding out from an invoice.

💡 Result and what we took away

~$1,500/month → ~$200/month, just by moving an existing, years-old distribution onto the Business flat-rate plan — no architecture changes, no CDN swap, no new vendor, and the fix shipped within days of the client’s first call.

A few takeaways from this one:

  • A shocking invoice is often just an outdated pricing decision, not an architecture problem. The client didn’t need to change anything about how their system worked — just how it was billed.
  • Measure before you migrate. Comparing real (peak-month-inclusive) usage against the published allowances is what let us confidently recommend Business over Premium.
  • Legacy config is the real migration cost, not the plan itself. OAI → OAC and ForwardedValues → cache policies were things worth cleaning up regardless — the plan migration just gave the client a concrete reason to finally do it.
  • A soft usage allowance with a grace period is a very different risk profile than a hard quota — worth explaining clearly to a client so “what if we go over during the next big sale?” isn’t a blocker.

If you’re running a CloudFront distribution that’s been around since the pay-as-you-go-only era — especially one that gets seasonal spikes — it’s worth 20 minutes to pull the usage numbers and check whether a flat-rate plan already pays for itself.

📚 References