Course outline

11.3

CloudFront Functions vs Lambda@Edge

The four event points, limits side by side, and which one fits each use case.

20 min Reading + animations

Tip: tap or hover any dotted-underlined term to see what it means.

By the end of this lesson you will be able to

  • Explain what an edge function is, why you would run code inside a CDN, and which problems it solves better than the origin.
  • Name the four CloudFront event points, say exactly when each one runs, and predict which run on a cache hit, a miss, an origin error and a function-generated response.
  • Compare CloudFront Functions and Lambda@Edge on runtime, scale, duration, memory, package size, network and body access, where they run and price, using today’s limits.
  • Use CloudFront KeyValueStore for settings that change without a redeploy, and know the newer origin modification helpers.
  • Deploy Lambda@Edge correctly (us-east-1, numbered versions, replication, logs in the Region where it ran) and diagnose 502 and 503 errors from edge functions.
  • Pick the right tool for a scenario, including the cheaper answers: an origin event instead of a viewer event, or no function at all.

#Code inside the CDN

#What an edge function is

CloudFront (lesson 11.1) caches your content in hundreds of edge locations. Most of the time it just stores and serves bytes. But many modern sites need a little logic on the way: send old links to new pages, add security headers, check a login token, pick a version of a page for an experiment, shrink an image for a phone.

You could do all of that at the origin. Then every such request has to travel to the origin Region, the origin must scale for it, and a lot of it cannot be cached. An edge function is code you write and attach to a CloudFront distribution, so it runs close to the viewer, inside the CDN, before or after the cache.

The slides sum up the deal, and it is worth remembering in your own words:

  • You attach code to a distribution’s cache behaviour; CloudFront runs it near your users, so the extra latency is tiny.
  • There are no servers to manage and nothing to deploy per Region: CloudFront takes the code everywhere.
  • It is fully serverless and you pay only for what runs.
  • The purpose is to customise what the CDN delivers.

CloudFront offers two kinds: CloudFront Functions and Lambda@Edge. They look similar from far away and are completely different up close.

#What people use them for

AWS lists the jobs edge functions are typically used for. Here is each one with an everyday example from an online shop in Dhaka, Haatbazar, served at shop.example.com through d111111abcdef8.cloudfront.net:

Use caseHaatbazar exampleUsually
Website security and privacyAdd HSTS and anti-clickjacking headers; strip the Server headerCloudFront Functions (or a response headers policy)
Dynamic web application at the edgeBuild a small personalised banner from a cookie and a database readLambda@Edge
Search engine optimisationRedirect duplicate URLs to one canonical URL; serve prerendered pages to crawlersCloudFront Functions for redirects, Lambda@Edge for prerendering
Route intelligently across originsSend wholesale buyers to a different catalogue originEither (see origin modification below)
Bot mitigation at the edgeBlock requests without a valid signed cookieCloudFront Functions; AWS WAF Bot Control for real bot management
Real-time image transformationResize a 4 MB product photo to 400 pixels for a phoneLambda@Edge
A/B testingShow the new checkout to 10% of visitorsCloudFront Functions with KeyValueStore
User authentication and authorisationValidate a JWT before the members-only price listCloudFront Functions; Lambda@Edge if the check must call an identity service
User prioritisationSend logged-in buyers past a waiting room during Eid salesEither
User tracking and analyticsSet a visitor ID cookie on the first visitCloudFront Functions

#The four event points

Every request through CloudFront passes four points where code can be attached. This is the part the exam asks about most.

  1. Viewer request

    Runs when CloudFront receives the request from the viewer, before it checks the cache. Whatever it changes (URL, headers, cookies, query string) shapes the cache key. It can also answer on its own, for example with a redirect or a 401. Runs on every request, hit or miss.

  2. Origin request

    Runs only when CloudFront is about to forward the request to the origin, that is on a cache miss (or an expired object). On a hit it does not run at all. Good for choosing an origin, adding a secret header, or a lookup whose result will be cached.

  3. Origin response

    Runs after CloudFront receives the origin’s response and before it caches it. It runs even when the origin returns an error, so it can replace a 404 or 503. What it changes is cached for everyone.

  4. Viewer response

    Runs before CloudFront returns the response to the viewer, on hits and misses. Changes here are per viewer and not cached, for example setting a cookie.

The key difference between the two kinds starts right here:

  • CloudFront Functions can run only on viewer request and viewer response.
  • Lambda@Edge can run on all four.

Watch a miss, a hit, and the cases where a trigger is skipped:

The four event points on one request

Top row: the request travels from the viewer to the origin. Bottom row: the response comes back. Both kinds of function can hook the two viewer events; only Lambda@Edge can hook the two origin events, and those run only when CloudFront actually goes to the origin.

Scenario

The first visitor asks for a product page nobody has asked for at this edge yet.

Viewerin Dhaka
Viewer requesteither kindruns
Edge cachehit or miss?
Origin requestLambda@Edge only
Originap-south-1
Origin responseLambda@Edge only
Viewer responseeither kind
GET /product/42
Step 1 of 8
1

GET /product/42 arrives at the edge location. The viewer request function runs first, before CloudFront even looks in the cache, so it can change the URL, headers or cookies that make up the cache key, or answer on its own.

#When a trigger does not run

The happy path is easy. The exceptions are where production surprises and exam distractors live:

TriggerDoes not run when…
Viewer requestCloudFront redirects HTTP to HTTPS itself (viewer protocol policy); CloudFront fetches a custom error page
Origin requestThe object is in the cache and still fresh (a hit)
Origin responseThe object came from the cache; the response was generated by an origin request function
Viewer responseThe origin returned 400 or higher; a custom error page is returned; the response was generated by a viewer request function; the HTTP-to-HTTPS redirect

Two consequences matter in design. First, logic in origin events runs only on misses: with a 95% hit ratio, it runs for 1 request in 20, and you pay for 1 in 20. Second, anything you need on every response, including errors, should not live only in a viewer response function; a response headers policy covers error responses too.

#One function per event, and how the two kinds combine

Each cache behaviour can have one function per event type, so at most four. You can mix the two kinds, with one rule: CloudFront Functions and Lambda@Edge cannot both be used on viewer events of the same behaviour. So “CloudFront Function on viewer request + Lambda@Edge on origin request” is allowed and common; “CloudFront Function on viewer request + Lambda@Edge on viewer response” is not.

Every function also adds its run time to the request: CloudFront waits for it to finish before it continues. That is why a viewer request function, which runs on every request, must be fast.

Self-checkQuestion

Haatbazar’s product pages have a 96% cache hit ratio. A function that adds a header must run once for each request that reaches the origin, and its result should be cached. Which event should it use?

#CloudFront Functions: the bicycle

#What they are

CloudFront Functions are small JavaScript functions that run in the edge locations themselves, inside the request path, in a very light isolated runtime. They are a native CloudFront feature: you write, test and publish them in the CloudFront console or API, with no Lambda involved and no Region to choose.

What makes them special is the limit on everything:

  • Language: JavaScript only, in a restricted runtime (version 5.1 of the language standard with selected newer features; runtime 2.0 adds const, let, async/await, a crypto module and KeyValueStore).
  • Duration: sub-millisecond. CloudFront measures it as compute utilization, 0–100% of the allowed time; a function that goes over is stopped and the viewer gets an error.
  • Memory: 2 MB. Code size: 10 KB, including any data you paste in.
  • No network access, no file system, no request body, no timers, no eval. Everything the function knows comes from the request (method, URI, query string, headers, cookies, viewer IP) and from its KeyValueStore.
  • Geolocation and device headers such as CloudFront-Viewer-Country are available (when you add them through a cache or origin request policy).
  • Scale: millions of requests per second, instantly.
  • Events: viewer request and viewer response only.
  • Price: $0.10 per million invocations, nothing for duration, and the first 2 million a month are free. That is the “about 6 times cheaper” in the notes: Lambda@Edge charges $0.60 per million requests before duration.

#The jobs they are made for

AWS names four, and they match the notes exactly:

  1. Cache key normalisation. Turn /Product/42?utm_source=fb&fbclid=x9 and a hundred similar URLs into /product/42, so they share one cached copy. The hit ratio goes up and the origin load goes down.
  2. Header manipulation. Insert, change or delete request or response headers: add True-Client-IP for the origin, add security headers, remove headers that leak information.
  3. URL redirects and rewrites. Send oldsite.example to newsite.example with the path kept, or rewrite /about to /about/index.html for an S3 origin.
  4. Request authorisation. Validate a hashed token such as a JWT (signature and expiry) and answer 401 at the edge, without calling anyone.

A complete redirect function is a handful of lines:

function handler(event) {
  var req = event.request;
  if (req.headers.host && req.headers.host.value === 'oldsite.example') {
    return {
      statusCode: 301,
      statusDescription: 'Moved Permanently',
      headers: { location: { value: 'https://newsite.example' + req.uri } },
    };
  }
  return req; // not the old host: carry on to the cache
}

Returning the request lets it continue; returning a response object answers the viewer immediately. A viewer response function receives the response (and the request) and returns the response, changed.

#KeyValueStore: settings without a redeploy

A 10 KB function cannot hold a list of 5,000 old URLs, and editing code to change an experiment from 10% to 50% is slow and risky. CloudFront KeyValueStore solves both: a global, low-latency key-value datastore that a CloudFront Function can read at the edge.

  • You create a store, add keys through the console, CLI or API, and associate it with the function (one store per function; a store can serve up to 100 functions).
  • The function reads values with await kvs.get(key) (runtime 2.0). The read is local to the edge, not a network call.
  • Updates spread to all edge locations within seconds, with no function redeploy.
  • Limits: keys up to 512 bytes, values up to 1 KB, 5 MB per store. Reads cost $0.03 per million (2 million free a month); other API calls $1 per 1,000.
  • It is read-only from the function, and only CloudFront Functions can use it, not Lambda@Edge.

Typical contents: a redirect map, A/B percentages and feature flags, an allow list of partner IDs, the secret used to check JWT signatures.

#Choosing the origin from a CloudFront Function

Since late 2024, a viewer request CloudFront Function (runtime 2.0) can also change the origin of a request with helper methods: cf.updateRequestOrigin() (change or set the origin’s domain, timeouts, headers, OAC…), cf.selectRequestOriginById() (switch to another origin already in the distribution) and cf.createRequestOriginGroup() (build a failover pair on the fly). Before, only Lambda@Edge on the origin request could do that.

There is a cost trade-off AWS itself points out: a viewer request function runs on every request, while a Lambda@Edge origin request function runs only on misses. For highly cacheable content, Lambda@Edge can be the cheaper way to route between origins. For the exam, “dynamic origin selection” with network lookups still points to Lambda@Edge; the CloudFront Functions helpers are a good side note.

Watch the typical jobs, and the limits that send a job elsewhere:

CloudFront Functions at work

Small, fast jobs on every request at the edge location: redirects, cache key clean-up, headers, an A/B split read from KeyValueStore, a token check. Then the two things a CloudFront Function cannot do.

Scenario

The shop moved from oldsite.example to newsite.example; old links are everywhere.

Viewerbrowser
CloudFront Functionat the edge
KeyValueStoreread only
Edge cache
Originap-south-1
GET oldsite.example/eid-sale
Step 1 of 3
1

An old link from a Facebook post. The distribution serves both names, and a viewer request function is attached to the behaviour.

#Lambda@Edge: the sports car

#What it is

Lambda@Edge is an extension of AWS Lambda (taught in depth in chapter 15, Lambda basics). For this lesson you only need this much: a Lambda function is code that AWS runs when an event arrives, billed per request and per millisecond of run time, with an IAM execution role that gives it permissions. Lambda@Edge takes such a function and lets CloudFront events trigger it.

  • Languages: Node.js and Python, with any libraries you bundle, including the AWS SDK.
  • Events: all four: viewer request, viewer response, origin request, origin response.
  • Duration: up to 5 seconds on viewer events and 30 seconds on origin events.
  • Memory: 128 MB on viewer events; on origin events up to 10,240 MB (10 GB), with CPU growing with memory.
  • Package size: up to 50 MB compressed, for both event types today (it used to be 1 MB for viewer events).
  • Network access: yes. It can call DynamoDB, S3, any AWS service or any API on the internet.
  • File system (/tmp) and request body access: yes. The body is offered only if you tick include body; it arrives base64-encoded and is cut at 40 KB on a viewer request and 1 MB on an origin request.
  • Geolocation and device headers: only on origin events (CloudFront adds them after the viewer request).
  • Scale: up to about 10,000 requests per second per Region, and it shares the Region’s Lambda concurrency quota (1,000 by default) with your other Lambda functions.
  • Price: $0.60 per million requests plus $0.00005001 per GB-second of run time, metered per millisecond. No free tier.

#Where it runs, and how it gets there

You create a Lambda@Edge function only in US East (N. Virginia), us-east-1. You publish a numbered version (never $LATEST or an alias) and associate that version’s ARN with a cache behaviour and an event. CloudFront then replicates the function to AWS Regions around the world, which takes a few minutes.

When an event fires, the function runs in the AWS Region nearest to the edge location that received the request, the same tier as the Regional Edge Caches (lesson 11.1), not in the edge location itself. That is a little further from the viewer than a CloudFront Function, which is one reason a viewer-event Lambda@Edge adds more latency.

Two practical consequences:

  • Logs land where the function ran. CloudWatch Logs gets a log group named /aws/lambda/us-east-1.<function-name> in each Region where it executed. A viewer in Dhaka produces logs in ap-south-1 (Mumbai), not in us-east-1.
  • Deleting takes patience. You cannot delete the function while replicas exist: remove it from every distribution, wait for CloudFront to delete the replicas (it can take a few hours), then delete it.

Some Lambda features are not supported at the edge: environment variables, VPC access, layers, the arm64 architecture, container images, dead-letter queues, X-Ray, provisioned concurrency and more than 512 MB of ephemeral storage. The execution role must trust both lambda.amazonaws.com and edgelambda.amazonaws.com.

Lambda@Edge: written in us-east-1, run everywhere

You create the function once in US East (N. Virginia). CloudFront copies a numbered version to AWS Regions around the world and runs it in the one nearest each viewer’s edge location.

Scenario

The shop’s first Lambda@Edge function goes live.

us-east-1
ap-south-1
eu-west-2
Developer
edge-fn:3version 3
CloudFrontdistribution
Viewerin Dhaka
create, Node.js
Step 1 of 5
1

The developer creates the function in us-east-1, the only Region where Lambda@Edge functions can be created. Its execution role must trust both lambda.amazonaws.com and edgelambda.amazonaws.com.

#The jobs it is made for

AWS’s list for Lambda@Edge is the mirror image of the CloudFront Functions limits:

  • functions that take several milliseconds or more;
  • functions that need adjustable CPU or memory;
  • code that depends on third-party libraries, including the AWS SDK for other AWS services;
  • functions that need network access to external services;
  • functions that need file system access or the body of the HTTP request.

In the notes’ words, that means:

  • Dynamic content generation: build a page or fragment per request, for example a personalised offer from the customer’s segment.
  • External API and database calls: look up a session in a third-party service or a user’s tier in DynamoDB (exam trick 2).
  • Image optimisation: resize an image on the fly for the device’s screen, on an origin response for a missing size, and store the result.

Watch the jobs, a hit that skips the function entirely, and what slowness does:

Lambda@Edge at work

The jobs that need a real Lambda function: a DynamoDB lookup before the origin, resizing images on a miss, checking the request body. Then what happens on a hit, and when Lambda@Edge is slow or throttled.

Scenario

Wholesale buyers get a different catalogue origin; the mapping lives in DynamoDB.

Viewer
Edge cachemiss
Lambda@Edgenearest Region
DynamoDBglobal table
Originap-south-1
GET /catalogue (cookie: shop=17)
Step 1 of 6
1

The cache key includes the shop cookie, so each shop has its own cached catalogue. This one is not cached yet: a miss.

#Side by side

This table uses today’s AWS limits; the notes’ and slides’ older values are corrected in the last column.

CloudFront FunctionsLambda@EdgeCorrection to the notes/slides
RuntimeJavaScript onlyNode.js and Python—
EventsViewer request, viewer responseAll four—
Runs inEdge locations (closest to the viewer)The AWS Region nearest the edge location (the Regional Edge Cache tier)Notes said “Regional Edge Caches”; same tier, more precisely the nearest Region
ScaleMillions of requests per secondUp to about 10,000 per second per RegionSlides: “thousands”; that is the quota
Max durationSub-millisecond5 s viewer, 30 s originNotes “5 to 30 s” = viewer vs origin; slides “5–10 s” is outdated
Max memory2 MB128 MB viewer, up to 10 GB origin—
Code + libraries10 KB50 MB (viewer and origin)Notes “50 MB” is right; slides “1 MB – 50 MB” is the old viewer limit
Network, file systemNoYes—
Request bodyNoYes (include body; 40 KB viewer, 1 MB origin)—
Geolocation/device headersYesOrigin events only—
KeyValueStoreYes (runtime 2.0)No—
Build and test in CloudFrontYesNo (in Lambda, us-east-1)—
Price$0.10 per million, 2 million free a month$0.60 per million + GB-seconds, no free tier“About 6 times cheaper” is the request price alone

CloudFront FunctionsLambda@Edge

Pick it when the job is small and runs on every request: redirects and rewrites, cache key normalisation, header changes, JWT validation, A/B assignment from KeyValueStore, viewer-country logic.

Exam words: sub-millisecond, lightweight, highest scale, lowest latency, lowest cost, URL redirect, header manipulation, cache key.

Pick it when the job needs more: a call to DynamoDB or an API, the request body, a library or the AWS SDK, more than a few milliseconds, Python, or an origin request/response event.

Exam words: query a database at the edge, external network call, heavy computation, image resize, modify the request before it reaches the origin.

Try the trade-offs yourself. Tick what a job needs, or start from an example:

Which edge function fits?

Tick what the job needs, or start from an example. The verdict follows the AWS comparison table, and says which requirement decided it.

Examples

What the job needs

Tick at least one requirement to see a verdict.

#What it costs, and why the event matters

Where the code runs decides how often you pay. Take Haatbazar’s 100 million requests a month with a 90% hit ratio and a function that runs 5 ms at 128 MB:

  • CloudFront Function on viewer request: 100 M invocations, minus 2 M free = 98 M × $0.10 per million = $9.80.
  • Lambda@Edge on viewer request: 100 M × $0.60 per million = $60, plus 100 M × 0.005 s × 0.125 GB = 62,500 GB-s × $0.00005001 ≈ $3.13, total ≈ $63.
  • Lambda@Edge on origin request: only the 10 M misses: $6 + $0.31 ≈ $6.31.

So the bicycle is cheapest per run, but the sports car parked at the origin event can be cheaper still, because it runs ten times less often. Change the numbers:

What does the edge job cost?

Pick the traffic and the cache hit ratio. The same job is priced three ways: where it runs decides how often you pay.

Requests per month (millions)

Cache hit ratio

Lambda@Edge average duration

Lambda@Edge memory

CloudFront Function, viewer request$9.80 per month

100M runs (every request)

Lambda@Edge, viewer request$63.13 per month

100M runs (every request)

Lambda@Edge, origin request$6.31 per monthcheapest

10M runs (cache misses only)

List prices, no free tier for Lambda@Edge, 2 million free CloudFront Function invocations a month. Data transfer and request charges of CloudFront itself are the same in all three and left out. A CloudFront Function can only do the light jobs, so the third row matters when the job is heavy anyway.

#What goes wrong

SymptomLikely causeFix
503 for some or all viewersThe function threw an error or timed out (Lambda@Edge: 5 s / 30 s), or a CloudFront Function went over its compute budgetTest it (test-function, compute utilization), catch errors, give network calls short timeouts and a fallback
503 only at peak, Lambda@EdgeThrottled: the Region’s Lambda concurrency or the 10,000 requests per second quotaRaise the concurrency quota in the Regions your viewers use; move work to origin events; use a CloudFront Function
502 right after a deployThe function returned an invalid response: a disallowed header (Connection, Keep-Alive…), a read-only header changed, a body over the limit (40 KB viewer, 1 MB origin), or a viewer request function that adds CloudFront-Viewer-CountryReturn only allowed fields within the limits
Origin request function “never runs”The objects are cache hitsExpected; use viewer request if it must run every time
Security header missing on error pagesViewer response is skipped for status 400 and aboveUse a response headers policy, or set it in origin response
Viewer response cannot change the statusLambda@Edge viewer response functions cannot modify the status codeDo it in origin response, or generate the response at viewer request
Function not listed when associatingLambda function created outside us-east-1, or $LATEST/alias chosenCreate it in us-east-1 and publish a version
“No logs” for Lambda@EdgeLooking in us-east-1Look in the Region near the viewers: /aws/lambda/us-east-1.<name>
Wrong content cached for other usersA viewer request function varies the response on a header or cookie that is not in the cache keyPut that value in the cache key (cache policy) or rewrite the URI so the key differs
Cannot delete the Lambda functionReplicas still existRemove all associations, wait for replicas to go, then delete

#Edge functions in system design

  • The serverless front door. Static site in S3 behind CloudFront with OAC (lessons 10.3 and 11.1), a CloudFront Function for redirects, clean URLs and security, and the real API on API Gateway and Lambda (chapter 15). No servers anywhere.
  • Protect the origin. Reject bad tokens, oversized requests and junk paths at the edge, so the origin only sees work worth doing. For attack patterns (SQL injection, XSS, rate limits, bots) use AWS WAF on the distribution (lesson 11.2) instead of hand-written rules.
  • Raise the hit ratio. Normalise the cache key with a CloudFront Function; often the cheapest performance win in the whole stack.
  • Personalise without losing the cache. Put the segment (country, device, A/B group, shop tier) into the cache key, so each segment is cached once, instead of building every page at the origin.
  • Route across origins and Regions. Choose an origin by country, by user tier from DynamoDB, or by a weight in KeyValueStore. For plain availability failover, origin groups (lesson 11.1) need no code; for TCP/UDP acceleration and static IPs, see Global Accelerator (lesson 11.4).
  • Know when not to use one. Fixed headers → response headers policy. Country blocking → geo restriction (lesson 11.2). Private content → signed URLs or cookies (lesson 11.2). Heavy business logic → the origin. An edge function is the right tool when the logic must run near the viewer and no built-in setting does it.

#Try it yourself

CloudFront Functions, end to end with the AWS CLI. redirect.js holds the redirect function shown above:

# 1. Create the function (it starts in the DEVELOPMENT stage)
aws cloudfront create-function --name haat-redirect \
  --function-config Comment="old host to new",Runtime=cloudfront-js-2.0 \
  --function-code fileb://redirect.js

# 2. Test it with a sample viewer request event; look at FunctionOutput and ComputeUtilization
aws cloudfront describe-function --name haat-redirect          # note the ETag
aws cloudfront test-function --name haat-redirect --if-match <ETag> \
  --event-object fileb://event-old-host.json --stage DEVELOPMENT

# 3. Publish to LIVE, then attach it to a cache behaviour (FunctionAssociations, EventType viewer-request)
aws cloudfront publish-function --name haat-redirect --if-match <ETag>
aws cloudfront get-distribution-config --id E1A2B3C4D5E6F7 > dist.json   # edit, then update-distribution

# 4. KeyValueStore for settings
aws cloudfront create-key-value-store --name haat-settings
aws cloudfront-keyvaluestore put-key --kvs-arn <store ARN> --key checkout_b_percent --value 10 --if-match <ETag>

Lambda@Edge (it must be us-east-1):

aws lambda create-function --region us-east-1 --function-name haat-resize \
  --runtime nodejs22.x --handler index.handler --role arn:aws:iam::111122223333:role/edge-role \
  --zip-file fileb://resize.zip --timeout 30 --memory-size 1024
aws lambda publish-version --region us-east-1 --function-name haat-resize    # returns version 1
# associate arn:aws:lambda:us-east-1:111122223333:function:haat-resize:1 with EventType origin-response

# Where did it run? Logs are in the Region near the viewers:
aws logs describe-log-groups --region ap-south-1 --log-group-name-prefix /aws/lambda/us-east-1.haat-resize

Then watch the edge from outside:

curl -sI https://oldsite.example/eid-sale | grep -i -E '^(HTTP|location|x-cache|x-amz-cf-pop)'
# HTTP/2 301, location: https://newsite.example/eid-sale, x-cache: FunctionGeneratedResponse from cloudfront

curl -sI "https://shop.example.com/Product/42?utm_source=fb" | grep -i -E '^(x-cache|age|x-amz-cf-pop)'
curl -sI "https://shop.example.com/product/42?utm_source=x" | grep -i -E '^(x-cache|age|x-amz-cf-pop)'
# the second one should say Hit from cloudfront: both normalised to the same cache key

x-cache shows Hit, Miss, RefreshHit or FunctionGeneratedResponse; age shows how long the object has been cached; x-amz-cf-pop names the edge location (an airport-style code, for example one starting with BOM for Mumbai or SIN for Singapore).

#Summary

Key takeaways

  • An edge function is code attached to a CloudFront cache behaviour that runs near viewers; serverless, deployed globally by CloudFront, pay per use. Two kinds: CloudFront Functions (bicycle) and Lambda@Edge (sports car).
  • Four events: viewer request (before the cache, every request), origin request (misses only), origin response (before caching, even on errors), viewer response (every response below 400). CloudFront Functions: viewer events only. Lambda@Edge: all four.
  • One function per event type per behaviour; the two kinds cannot share viewer events of one behaviour, but CloudFront Function on viewer + Lambda@Edge on origin is fine.
  • CloudFront Functions: JavaScript, sub-millisecond, 2 MB memory, 10 KB code, no network, no body, no file system, millions of requests per second, edge locations, $0.10 per million (2 million free). Jobs: cache key normalisation, headers, redirects/rewrites, JWT checks. KeyValueStore gives them editable settings (5 MB per store).
  • Lambda@Edge: Node.js or Python, created in us-east-1, numbered version, replicated, runs in the nearest Region; 5 s / 128 MB on viewer events, 30 s / up to 10 GB on origin events, 50 MB package; network, body and file system access; about 10,000 requests per second per Region; $0.60 per million + duration, no free tier. Jobs: DynamoDB or API calls, image resizing, dynamic content, body inspection.
  • Exam tricks: sub-ms / header / highest scale / lowest latency / cheapest redirect → CloudFront Functions; database or network call / heavy compute / origin request → Lambda@Edge; fixed headers only → response headers policy.
  • Errors: 503 = the function failed, timed out or was throttled; 502 = it returned something invalid. Lambda@Edge logs are in the Region where it ran.