AWS’s in-family edge split: the sub-millisecond sandbox against the full Lambda runtime, with the cost maths shown.
Winner depends on your workload.
Winner depends on: whether your logic needs network calls, origin-side triggers or more than a restricted JavaScript sandbox — capability decides this one; cost merely punishes choosing wrong.
Side by side
| CloudFront Functions | Lambda@Edge | |
|---|---|---|
| Runtime | Restricted JavaScript, no network/filesystem access | Full Node.js or Python |
| Triggers | Viewer request / viewer response only | All four: viewer + origin, request + response |
| Runs at | Every CloudFront edge location | Regional edge caches |
| Limits | ~10 KB code, ~1 ms budget; KeyValueStore for config | 5 s / 1 MB (viewer), 30 s / 50 MB (origin); 128 MB–10 GB memory |
| Pricing | $0.10 per million invocations; 2M/month free; no duration billing | $0.60 per million requests + GB-second duration; no free tier |
| Deploy | In CloudFront directly, no IAM role | Author in us-east-1, replicate; minutes to propagate |
One CDN, two compute products
AWS ships two ways to run code inside CloudFront, and the naming hides how different they are. CloudFront Functions is a purpose-built sandbox: restricted JavaScript, sub-millisecond execution, viewer-facing events only, running at every edge location. Lambda@Edge is real Lambda — Node.js or Python, network access, up to 30 seconds of work — replicated to CloudFront’s regional edge caches and wired into all four lifecycle events. Choosing between them is a capability checklist, not a preference.
The capability checklist
Four questions settle it. Does the logic need network calls — a JWKS fetch, a DynamoDB lookup, an external API? Lambda@Edge; Functions has no network access at all. Does it need origin-request or origin-response triggers — origin selection, response rewriting on cache miss? Lambda@Edge; Functions fires only on viewer request and response (with limited origin-routing support for origins already defined on the distribution). Does the code exceed roughly 10 KB compiled, need npm packages, async/await or the request body? Lambda@Edge. If every answer is no — header manipulation, URL rewrites, redirects, cache-key normalization, simple token checks, A/B bucketing — CloudFront Functions is correct by an order of magnitude, and the KeyValueStore covers lightweight config without network calls.
The cost maths, shown
Functions bills one meter: $0.10 per million invocations, with 2 million a month inside CloudFront’s always-free tier and no duration charge. Lambda@Edge bills two: $0.60 per million requests plus GB-second duration — and the standard Lambda free tier does not apply. Worked example at 100 million viewer requests/month: Functions costs $10. The same trigger on Lambda@Edge at 128 MB and 50 ms averages roughly $60 in requests plus ~$32 duration ≈ $92 — the commonly cited 6× gap on invocations alone, and nearer 10× once duration is counted. The expensive failure mode is architectural: a viewer-request Lambda attached to a behavior matching static assets fires on every cached hit; at 1.5 billion asset requests a month that is $900 of invocations for logic that mostly does nothing. Scope functions to the path patterns that need them. Figures checked against provider documentation, July 2026.
Operational differences that bite
Runtime capability inside the sandbox is narrower than the JavaScript label implies: CloudFront Functions runs a restricted engine — the current runtime extends an ES5.1 baseline with selected ES6 features — with no Promises-based network work to await and no response-body access, so anything that transforms payloads rather than headers and URLs is Lambda@Edge territory by definition. Budget your migration reviews accordingly: rewriting a Lambda down to a Function is usually an afternoon; discovering mid-rewrite that you needed the body is a wasted one.
Functions lives inside CloudFront: no IAM execution role, test API in-console, near-instant deployment. Lambda@Edge must be authored in us-east-1, published as a version, and associated with the distribution — then replicated, with propagation measured in minutes and cold starts adding 100–200 ms on viewer-request paths during spikes. Neither supports environment variables conventionally, and both are famously hard to debug at the PoP level — instrument early. The two coexist happily on one distribution: Functions on every request for the cheap fast work, Lambda@Edge on cache-miss origin events for the heavy lifting — the pattern most mature CloudFront estates converge on.
How to decide
Default to CloudFront Functions and escalate only when the checklist forces you to — that discipline alone regularly cuts edge-compute lines by half in the estates we audit. For the cross-vendor view of the same design space, our Fastly Compute vs Cloudflare Workers and EdgeWorkers vs Workers pieces show how differently the non-AWS edges split this problem.
Auditing an edge-compute bill that grew quietly? The assessment maps every function to the cheapest runtime that can carry it.
