Analyzing CDN cost efficiency: a developer's comparison
Start a CDN cost comparison with monthly bytes and requests, then check which plans can serve your content. For the website workload below, CloudFront’s usage-priced delivery subtotal is $71.28, while its Pro flat-rate plan is $15. That difference makes comparing specific offers just as important as comparing providers.
Define one monthly workload
This is a constructed budgeting example, not a customer invoice or performance benchmark. It models one public website serving HTML, CSS, JavaScript, and modest supporting images, with no video, large-file downloads, uploads, or image transformations.
| Monthly input | North America, served in the US | Europe | Total |
|---|---|---|---|
| Viewer response bytes, after compression and including HTTP headers | 1,200,000,000,000 | 800,000,000,000 | 2,000,000,000,000 |
| Successful HTTPS GET requests | 3 million | 2 million | 5 million |
Assume one domain and one distribution or service, an entire billing month, unused free allowances, and no other account usage. The regional split is 60/40 for both measures here; collect bytes and requests separately from your own logs. Map traffic to each provider’s billing regions, rather than assuming a visitor’s country always identifies the serving location.
All prices and allowances below were checked on September 22, 2026. Amounts are USD before tax, using public pricing without negotiated discounts or promotional credits. The comparison excludes origin hosting, storage, origin requests and transfer, optional edge compute, transformations, log destinations, and additional paid security or support. Included bundle features remain included; these offers do not provide identical feature sets.
Compare the actual CDN offers
| Offer | Published basis for this workload | Monthly delivery estimate or listed plan fee |
|---|---|---|
| Cloudflare website Free / Pro | Free includes CDN; Pro is $25 billed monthly, or $20/month billed annually. Use monthly billing here. | $0 / $25, subject to content eligibility |
| CloudFront pay-as-you-go | 1 TB transfer and 10 million HTTP/S requests free each month; the next transfer band is $0.085 per AWS GB in both selected regions. | $71.28 for viewer delivery |
| CloudFront Pro flat-rate | $15 per distribution/month; 50 TB and 10 million requests included. | $15, if its features fit |
| Fastly Full Site Delivery, current usage pricing | Regional bands: first 100 GB and 1 million requests free; then $0.12/GB in North America and Europe, plus $0.01 per 10,000 requests. | $219 for viewer delivery |
| Fastly Network Services Basic package | Listed at $1,500/month with 100 million requests and Standard support. | $1,500 listed fee; obtain contract terms |
Cloudflare Free is a real option if its features suffice; buying Pro is not required simply to use its CDN. CloudFront’s $0 flat-rate plan has smaller allowances, 100 GB and 1 million requests, so this workload exceeds it. Its pay-as-you-go free tier is a separate offer, not an extra allowance to stack onto Pro. AWS lists the flat-rate tiers separately.
The usage-priced rows assume no term commitment. CloudFront flat-rate plans do not require an annual commitment. Fastly’s package commitment, bandwidth terms, and excess-usage treatment need a quote; a monthly sticker price does not establish those terms. Its current rate card also links separate legacy pricing for online accounts created before November 4, 2025.
Check eligibility and required features
Cloudflare’s website plans are not a blanket allowance for media delivery. Its CDN terms require appropriate paid services for video and other large files outside Enterprise, and permit limits for disproportionate image, audio, or large-file delivery. Price a video or image service separately if that describes your workload.
Fastly’s package restrictions target web pages and APIs, exclude streaming, and limit traffic originating in the African, Indian, or South Korean billing regions to 10%. Our US/Europe example avoids that regional constraint, but it does not establish eligibility for every package term.
CloudFront Pro’s transfer allowance fits this example, but custom cache policies and an uptime SLA start at Business. A site needing those features must reconsider the $15 row. Flat-rate plans cover one distribution and up to one apex domain; sustained substantial excess usage can cause delivery adjustments despite no overage charges. Check the feature and allowance rules, including historical-usage eligibility. AWS also requires an eligible account rather than a Free Tier account.
Before treating two prices as alternatives, write down your required caching controls, WAF rules, bot protection, log retention, support response, and availability commitment. A low delivery subtotal does not price missing requirements.
Reproduce the delivery calculation
Keep the original byte count when comparing units. Fastly uses decimal GB, so this workload is 2,000 GB. AWS describes CloudFront transfer in binary GB, which we label GiB here: the same bytes are approximately 1,862.645149 GiB, with a 1,024 GiB free allowance. See Fastly’s billing measurements and AWS’s unit explanation, in Portuguese.
For CloudFront, subtract the allowance once across the account:
max(0, 2,000,000,000,000 / 1,073,741,824 − 1,024) × $0.085 = $71.28.
Both regions have the same transfer rate at this volume, so the allocation between them does not
change that result. All five million requests fit within the separate request allowance.
For Fastly, apply the published regional free bands once per billing region:
| Component | Calculation | USD |
|---|---|---|
| North America transfer | (1,200 − 100) GB × $0.12 | 132.00 |
| Europe transfer | (800 − 100) GB × $0.12 | 84.00 |
| North America requests | (3,000,000 − 1,000,000) / 10,000 × $0.01 | 2.00 |
| Europe requests | (2,000,000 − 1,000,000) / 10,000 × $0.01 | 1.00 |
| Viewer delivery subtotal | 132 + 84 + 2 + 1 | 219.00 |
The following offline calculator reproduces those two subtotals. It deliberately accepts only North America and Europe, at most 10 decimal TB combined, and at most 10 million requests combined. Those bounds keep it inside the transfer bands above and CloudFront’s free request allowance. Larger workloads need more pricing bands, not removal of the guard.
Save this as a new file named cdn-cost.ts. It needs Node.js with native TypeScript support and no
packages; the example was tested with Node.js 26.8.1 on Linux. It prints estimates, makes no network
requests, and writes no output files, so rerunning it leaves existing files untouched.
interface Usage {
bytes: number
requests: number
}
const workload: Record<'northAmerica' | 'europe', Usage> = {
northAmerica: { bytes: 1_200_000_000_000, requests: 3_000_000 },
europe: { bytes: 800_000_000_000, requests: 2_000_000 },
}
function estimate(traffic: typeof workload): Record<string, number> {
if (Object.keys(traffic).some((region) => region !== 'northAmerica' && region !== 'europe')) {
throw new Error('Only North America and Europe are priced')
}
const regions = [traffic.northAmerica, traffic.europe]
for (const region of regions) {
for (const value of [region.bytes, region.requests]) {
if (!Number.isSafeInteger(value) || value < 0) {
throw new Error('Use nonnegative whole bytes and request counts')
}
}
}
const bytes = regions.reduce((sum, region) => sum + region.bytes, 0)
const requests = regions.reduce((sum, region) => sum + region.requests, 0)
if (bytes > 10_000_000_000_000 || requests > 10_000_000) {
throw new Error('This example stops at 10 TB and 10 million requests')
}
const fastlyBandwidth = regions.reduce(
(sum, region) => sum + Math.max(0, region.bytes / 1_000_000_000 - 100) * 0.12,
0,
)
const fastlyRequests = regions.reduce(
(sum, region) => sum + (Math.max(0, region.requests - 1_000_000) / 10_000) * 0.01,
0,
)
return {
cloudFrontPayg: Math.max(0, bytes / 2 ** 30 - 1_024) * 0.085,
fastlyBandwidth,
fastlyRequests,
fastlyDelivery: fastlyBandwidth + fastlyRequests,
}
}
for (const [name, cost] of Object.entries(estimate(workload))) {
console.log(`${name}: USD ${cost.toFixed(2)}`)
}
Run it from the directory containing the file:
node cdn-cost.ts
Expected output:
cloudFrontPayg: USD 71.28
fastlyBandwidth: USD 216.00
fastlyRequests: USD 3.00
fastlyDelivery: USD 219.00
Edit the two regional totals to inspect a different month within the stated bounds. For example, 100 GB and one million requests in each region give a zero usage subtotal for both providers. Concentrating that same traffic in one region makes Fastly’s subtotal $13 because only one region’s free bands apply. These are arithmetic checks of this rate-card model, not verified invoices.
Fastly also bills CDN-to-origin bandwidth and, when enabled, shield-to-edge traffic. The $219 here excludes those paths; even a GET sends request headers toward the origin. Add them using Fastly’s billing definition before estimating a complete invoice. Neither usage subtotal includes the origin provider’s bill.
Separate cache hits from viewer traffic
An edge cache hit still delivers the response to the viewer. Improving the edge hit rate therefore does not reduce the viewer bytes or requests in this calculation when the requested responses stay the same. Smaller responses and browser caching can reduce viewer traffic; better edge caching primarily changes what reaches the origin.
Track two different ratios: the request hit rate counts requests answered from cache, while the byte hit rate weights hits by response size. In a simplified model where each miss fetches one complete response of the same size from the origin:
- At a 90% request hit rate, five million viewer requests imply 500,000 origin requests.
- At an 80% byte hit rate, 2,000 GB delivered to viewers imply 400 GB fetched from the origin.
- Raising only the byte hit rate to 95% reduces that origin volume to 100 GB, a 300 GB reduction. Viewer delivery remains 2,000 GB.
These are hypothetical traffic calculations. Revalidation, request collapsing, shielding, and different compression on the origin connection can change actual origin traffic. Cloudflare’s cache analytics documentation illustrates why a revalidation can contact the origin without downloading the response body again. Measure that traffic separately before assigning savings. AWS-origin transfer to CloudFront is already free under its published pricing, so do not attach an invented origin-egress saving to it; origin request or compute costs can still change.
Check the estimate against your application
Use a month of billing-region bytes and requests to replace the example, then price origin work and required extras separately. Keep image transformations, video processing, and edge function execution as distinct lines. If a feature shrinks responses, compare its charge with the resulting change in viewer and origin traffic rather than assuming it pays for itself.
Measure p95 TTFB, page-load behavior, and error rates for the users and cache states that matter to your application. A pricing table cannot establish which network performs best for them. Keep payloads and cache configuration comparable when evaluating alternatives.
Before committing, reconcile the model with an existing bill or a provider estimate, checking free allowance sharing, billing units, and the chosen account’s terms. Record any unexplained difference as an unresolved cost, not zero. That gives you a budget you can review when traffic or requirements change.
