Your CDN bill arrives as a single line item: $47,000 for bandwidth, requests, and add-ons. Finance asks which product teams drove the cost. Engineering wants to know if image optimization is worth it. Without attribution, everyone guesses. With proper per-team, per-service, and per-region tracking, you can answer precisely and optimize where it actually matters.
Why Aggregate CDN Billing Breaks Down at Scale
Most providers invoice by aggregated usage: total terabytes transferred, total requests, and feature surcharges. That works when one team owns one property. It fails when you run 40 microservices, 12 domains, and 5 teams behind a shared CDN distribution.
Aggregate billing hides three critical distortions:
- Cache efficiency variance: A video API with 92% hit ratio costs 8x less per GB than an uncacheable personalization API, but both show up as “bandwidth.”
- Request cost asymmetry: Small, uncacheable API calls can drive 70% of request charges while consuming 5% of bandwidth.
- Regional price arbitrage: Egress in North America and Europe is typically $0.02–$0.05/GB, while South America, Australia, and parts of APAC are $0.08–$0.14/GB. A launch in Brazil can double your effective rate without changing total volume.
Without attribution, cost optimization becomes political. Teams argue about who should reduce traffic, while the real levers — cache keys, origin shielding, and regional PoP selection — remain invisible. Attribution turns a finance problem into an engineering system you can instrument.
The Three Dimensions of Attribution
Effective attribution requires slicing the same bill three ways simultaneously. Each dimension answers a different stakeholder question.
| Metric | Edge Processing | Origin Processing | Improvement |
|---|---|---|---|
| Latency (p50) | 8–15 ms | 120–300 ms | 15–20x faster |
| Cache Hit Ratio | 85–95% | N/A | Reduces origin load |
| TLS Handshake | 1–5 ms (nearby PoP) | 50–150 ms | 10–30x faster |
| Bandwidth Cost | $0.01–0.04/GB | $0.05–0.12/GB | 3–5x cheaper |
| Availability | 99.99% (multi-PoP) | 99.9% (single DC) | 10x fewer outages |
1. Per-Service Attribution
Maps cost to a technical boundary: hostname, path, or microservice. Essential for understanding cache hit ratio, origin offload, and whether to tune cache invalidation or edge compute. Service is the most granular and most actionable layer.
2. Per-Team Attribution
Maps cost to an organizational owner for showback or chargeback. A team may own multiple services. This dimension drives accountability and budgeting. It requires a stable mapping table between service identifiers and team ownership.
3. Per-Region Attribution
Maps cost to the edge location that served the request, not the user’s location. This reveals geographic cost hotspots and informs decisions about tiered caching, origin placement, and whether to enable regional shielding. It also explains why two services with identical traffic have different bills.
These dimensions are orthogonal. A single request has all three attributes: service=checkout-api, team=payments, region=SA-East. Your pipeline must capture and join them at log level, not invoice level.
Tagging and Metadata: How to Make Traffic Identifiable
CDN logs are the source of truth, but raw logs lack business context. You must inject attribution metadata at the edge before the log is emitted.
The most reliable pattern is to add attribution headers via edge workers or CDN rules and log them:
# Cloudflare Worker / Fastly VCL / AWS CloudFront Function
addEventListener('fetch', event => {
let req = event.request;
let url = new URL(req.url);
let service = "web-frontend";
if (url.pathname.startsWith("/api/checkout")) service = "checkout-api";
if (url.pathname.startsWith("/api/images")) service = "image-service";
let headers = new Headers(req.headers);
headers.set("x-attribution-service", service);
headers.set("x-attribution-team", serviceMap[service].team);
headers.set("x-attribution-env", "prod");
return fetch(new Request(req, { headers }), req);
});
Alternatives if you cannot run edge compute:
- Separate hostnames or path prefixes per service — simple but breaks down for shared APIs.
- Distinct CDN distributions/zones per team — gives clean billing separation but increases operational overhead and loses shared cache benefits.
- Origin response headers — origin adds
x-service-idon cache MISS; edge logs it. Misses HITs, so you must also tag at edge.
Store the mapping in version control, not in the CDN console. A YAML file checked into Git that maps hostname + path regex to service and team owner ensures auditability. Sync it to your CDN via Terraform:
# Terraform: enforce attribution headers via CloudFront Functions resource "aws_cloudfront_distribution" "main" { # ... default_cache_behavior { function_association { event_type = "viewer-request" function_arn = aws_cloudfront_function.attribution.arn } } } # Tag the distribution itself for cost allocation tags = { Team = "platform" Service = "edge-router" CostCenter = "eng-infra-412" }
Log these headers alongside standard fields: cacheStatus, edgeLocation, bytesSent, requestTime. Without bytesSent and cacheStatus per request, you cannot reconstruct cost.
Per-Service Cost Tracking in Practice
Once logs are tagged, allocate cost proportionally. CDN pricing is tiered and often committed, so use weighted allocation rather than list price per request.
Step 1: Calculate billable usage per service from logs. Step 2: Apply your contract rates. Step 3: Allocate fixed fees (shield, WAF, image optimization) by the driver that incurs them.
| Service | Bandwidth (TB) | Requests (M) | Hit Ratio | Attributed Cost | Cost / 1M Req |
|---|---|---|---|---|---|
| image-service | 18.4 | 142.0 | 96.2% | $8,420 | $59.30 |
| web-frontend | 11.2 | 88.5 | 84.1% | $5,110 | $57.74 |
| checkout-api | 0.9 | 210.3 | 12.4% | $6,890 | $32.76 |
| video-manifest | 7.6 | 19.2 | 91.5% | $3,950 | $205.73 |
| personalization-api | 0.4 | 45.8 | 0.8% | $2,830 | $61.79 |
The table reveals what aggregate billing hides: checkout-api drives 40% of request volume but only 2% of bandwidth, yet it is your second-highest cost due to request fees and origin fetch. personalization-api has the worst unit economics — almost no cache hits. That is where HTTP/3 and connection coalescing won’t help; you need edge compute or response caching with surrogate keys.
Track cache performance metrics per service alongside cost: hit ratio, origin fetch bytes, and stale-while-revalidate ratio. A 5% hit ratio improvement on image-service at 18 TB saves more than eliminating personalization-api entirely.
Per-Team Showback vs. Chargeback
Showback is informational; chargeback hits budgets. Start with showback to build trust, then move to chargeback once attribution accuracy exceeds 95%.
Showback model: Publish a weekly dashboard by team with bandwidth, requests, and cost. Include trend and forecast. No finance integration. Goal is behavior change. Teams self-optimize when they see their service is 30% of the bill.
Chargeback model: Allocate actual invoice line items to cost centers. Requires handling of:
- Commitment discounts: If you have a $30k/month commit, distribute the discount proportionally to usage, not evenly. Otherwise low-usage teams subsidize high-usage teams.
- Shared costs: WAF, bot management, and TLS certificate costs should be split by protected requests, not bandwidth.
- Unattributed traffic: Keep it under 5%. Attribute the remainder to “platform/unmapped” and assign to the infrastructure team until fixed.
Example allocation SQL for BigQuery on CloudFront or Fastly logs:
-- Allocate monthly CDN cost per team, handling tiered pricing
WITH usage AS (
SELECT
x_attribution_team AS team,
SUM(bytes_sent)/1e12 AS tb,
COUNT(*) AS reqs,
SUM(CASE WHEN cache_status = 'Hit' THEN 1 ELSE 0 END)/COUNT(*) AS hit_ratio
FROM cdn_logs
WHERE DATE(timestamp) BETWEEN '2026-08-01' AND '2026-08-31'
GROUP BY 1
),
pricing AS (
SELECT 0.04 AS price_per_gb_na, 0.09 AS price_per_gb_sa, 0.085 AS price_per_gb_apac
)
SELECT team, tb, reqs, hit_ratio,
(tb*1024 * price_per_gb_na) + (reqs/1e6 * 0.0075) AS estimated_cost
FROM usage CROSS JOIN pricing
ORDER BY estimated_cost DESC;
Reconcile estimated cost to the actual invoice monthly. The delta should be <3%. If larger, you are missing surcharges or misclassifying regions.
Per-Region Tracking and Why It Changes Decisions
CDN vendors publish 4–8 regional price tiers, but your traffic mix determines your blended rate. Two companies with 50 TB/month can have $2,000 vs. $4,500 bills based solely on geography.
Per-region attribution requires logging edgePoP or coloId and mapping it to a billing region. Most providers use different region definitions in logs vs. invoices — build a translation table.
- North America & Europe: Cheapest, best cache offload. Optimize for hit ratio.
- South America (GRU, EZE, SCL): 2–3x NA price. Enable origin shield in São Paulo; consider a regional origin.
- APAC (NRT, SIN, SYD): High variance. Traffic from India and Southeast Asia often routes to Singapore with premium pricing.
- Middle East & Africa: Low volume but highest per-GB. Evaluate whether serving large assets there is necessary.
A practical win: one team moved image optimization from on-the-fly to pre-generated WebP/AVIF and enabled tiered cache in APAC. Bandwidth dropped 22% and APAC origin fetch fell 61%, saving $3,100/month — invisible without per-region data.
Building a Reliable Attribution Pipeline
Keep it simple and auditable. The pipeline has four stages:
- Tag: Edge worker injects
x-attribution-*headers. Log them. - Ship: Stream logs to object storage (S3/GCS) within minutes, then to warehouse hourly. Don’t rely on CDN dashboards for attribution.
- Enrich: Join logs with service catalog (service → team → cost center) and PoP → billing region map. Apply contract rates, including commits and overages.
- Publish: Daily team-level table and monthly invoice reconciliation. Alert if unattributed >5% or if estimated vs. invoiced delta >3%.
Common pitfalls: sampling logs to save cost (breaks attribution), using user geography instead of PoP for regional cost, and forgetting to attribute failed requests and 4xx/5xx — they are still billable.
Start with one distribution and two teams. Validate for a full billing cycle before rolling out. The goal is not perfect precision on day one, but a system that converges to <2% error within two months.
Frequently Asked Questions
What is the difference between showback and chargeback for CDN costs?
Showback reports CDN costs per team or service for visibility without actually billing them internally, encouraging optimization. Chargeback formally allocates and cross-charges the cost to team budgets, requiring precise attribution and finance integration.
How do you attribute CDN costs when cache hit ratio varies by service?
Attribute based on edge egress and request count rather than origin egress. Use CDN logs with service identifiers to split billable bandwidth and requests. Weight costs by cache hit ratio so low-hit services bear higher origin and compute costs.
Which CDN billing metrics should be tracked per region?
Track billable bandwidth/GB, HTTP/HTTPS requests, cache fill/origin fetch, Argo/smart routing, image optimization, and WAF/bot requests per PoP region. Regional pricing tiers differ 20-60%, so aggregate by continent and by high-cost regions like South America and APAC.
Can you do per-team CDN attribution without custom headers?
Yes, using hostname, path prefix, or distinct distribution/zone per team. However, custom headers or edge workers that inject x-team-id and x-service-id provide far more accurate attribution, especially for shared domains and microservices.
When attribution is in place, cost conversations shift from “the CDN is expensive” to “the personalization API costs $62 per million requests because it never hits cache — let’s fix that.” That is the point. Measure at the edge, allocate with business context, and optimize where the dollars actually go.