Lambda@Edge and CloudFront Functions
CloudFront can run code on requests and responses at the edge. There are two options, and they are not interchangeable.
Runtime
Section titled “Runtime”Lambda@Edge runs Node.js and Python functions in a Lambda execution environment at a Regional edge cache.
CloudFront Functions runs JavaScript in a purpose-built runtime inside the edge location itself. There are two runtime versions:
cloudfront-js-1.0— ECMAScript 5.1 with a few later additionscloudfront-js-2.0— ES 5.1 plus much of ES6 to ES12, includinglet,const, arrow functions, template literals,async/awaitand classes. Runtime 2.0 is required to read from CloudFront KeyValueStore.
Triggers
Section titled “Triggers”| Trigger | Lambda@Edge | CloudFront Functions |
|---|---|---|
| Viewer request | Yes | Yes |
| Origin request | Yes | No |
| Origin response | Yes | No |
| Viewer response | Yes | Yes |
CloudFront Functions run only on viewer request and viewer response, which means they run on every request including cache hits. Lambda@Edge origin triggers run only on a cache miss.
Performance and scale
Section titled “Performance and scale”| Lambda@Edge | CloudFront Functions | |
|---|---|---|
| Where it runs | Regional edge caches | Edge locations |
| Cold start | Tens of milliseconds | Effectively none |
| Maximum execution time | 30 seconds | Sub-millisecond, measured as compute utilisation |
| Memory | 128 MB to 10 GB | 2 MB |
| Package size | 50 MB compressed, including libraries | 10 KB |
| Generated response size | 40 KB (viewer triggers), 1 MB (origin triggers) | Not applicable |
| Network access | Yes | No |
| Filesystem access | Yes | No |
| Request body | Accessible | Not accessible |
Cold starts are the whole reason CloudFront Functions exists. A Lambda@Edge cold start is a real, viewer-visible delay measured in tens of milliseconds; a CloudFront Function has no meaningful startup cost.
What each is for
Section titled “What each is for”CloudFront Functions
- URL rewrites and redirects
- Request and response header manipulation
- Cache key normalisation
- Simple A/B testing by header or cookie
- Request validation, and simple token or signature checks
- Lookups against CloudFront KeyValueStore, using runtime 2.0
Lambda@Edge
- Authentication and authorisation against an external identity provider
- Calls to other AWS services or third-party APIs
- Image or content transformation
- Rules that need the request body
- Anything at origin request or origin response
CloudFront Functions is billed per invocation and is substantially cheaper. Lambda@Edge is billed per request and for compute duration.
Note the asymmetry in volume: a CloudFront Function on viewer request runs on every request, cache hits included, while a Lambda@Edge origin trigger runs only on cache misses. A high-hit-ratio distribution may invoke the function far more often than the Lambda.
Examples
Section titled “Examples”Lambda@Edge:
export const handler = async (event) => { const request = event.Records[0].cf.request; const headers = request.headers;
// External call, service access, body inspection: all available here const response = await fetch('https://api.example.com/data');
return request;};CloudFront Functions, runtime 2.0:
function handler(event) { const request = event.request; const headers = request.headers;
headers['x-custom-header'] = { value: 'some-value' };
return request;}Choosing
Section titled “Choosing”Reach for CloudFront Functions when the work is short, local and needs no network — header manipulation, rewrites, cache key normalisation — and latency and cost matter. Reach for Lambda@Edge when the work needs an external call, an AWS service, the request body, or a trigger at origin request or origin response.