Skip to content

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.

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 additions
  • cloudfront-js-2.0 — ES 5.1 plus much of ES6 to ES12, including let, const, arrow functions, template literals, async/await and classes. Runtime 2.0 is required to read from CloudFront KeyValueStore.
TriggerLambda@EdgeCloudFront Functions
Viewer requestYesYes
Origin requestYesNo
Origin responseYesNo
Viewer responseYesYes

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.

Lambda@EdgeCloudFront Functions
Where it runsRegional edge cachesEdge locations
Cold startTens of millisecondsEffectively none
Maximum execution time30 secondsSub-millisecond, measured as compute utilisation
Memory128 MB to 10 GB2 MB
Package size50 MB compressed, including libraries10 KB
Generated response size40 KB (viewer triggers), 1 MB (origin triggers)Not applicable
Network accessYesNo
Filesystem accessYesNo
Request bodyAccessibleNot 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.

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.

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;
}

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.