Sometimes serving cached content isn't enough — you need to run logic on the request or response itself. For example: redirect mobile users to a different URL, validate an authentication token before serving content, or rewrite URLs for A/B testing. AWS provides two services for running code at the edge, and choosing the wrong one is a common architectural mistake.
The Four Trigger Points
Before comparing the two services, understand where code can run in the CloudFront request lifecycle:
User → [Viewer Request] → CloudFront Cache Check → [Origin Request] → Origin
↓
User ← [Viewer Response] ← CloudFront Cache Store ← [Origin Response] ←┘
- Viewer Request: Fires when CloudFront receives a request from the user, before checking the cache. Runs on every single request.
- Origin Request: Fires only on a cache miss, just before CloudFront forwards the request to the Origin.
- Origin Response: Fires when CloudFront receives the response from the Origin, before caching it.
- Viewer Response: Fires just before CloudFront sends the response to the user.
1. CloudFront Functions (The Speed Demon)
CloudFront Functions are ultra-lightweight JavaScript snippets that run directly at the Edge Location (POP) — the server physically closest to the user. They are designed for simple, fast transformations.
| Property | Value |
|---|---|
| Runtime | JavaScript (ES5.1) |
| Execution location | Edge Location (POP) |
| Startup latency | Sub-millisecond |
| Max execution time | 1ms |
| Network access | ❌ None |
| File system access | ❌ None |
| Supported triggers | Viewer Request, Viewer Response only |
| Cost | ~1/6th the cost of Lambda@Edge |
Use cases: URL rewrites and redirects, HTTP header manipulation (adding security headers like Strict-Transport-Security), cache key normalization (stripping irrelevant query parameters), JWT structure validation (checking format and expiry without a DB call).
2. Lambda@Edge (The Heavy Lifter)
Lambda@Edge is a full AWS Lambda function (Node.js or Python) that runs at the Regional Edge Cache — one tier further from the user than CloudFront Functions, but with dramatically more capability.
| Property | Value |
|---|---|
| Runtime | Node.js, Python |
| Execution location | Regional Edge Cache |
| Startup latency | Standard Lambda cold start (100ms–500ms) |
| Max execution time | 5 seconds (Viewer triggers), 30 seconds (Origin triggers) |
| Network access | ✅ Full internet access |
| File system access | ✅ /tmp (512MB) |
| Supported triggers | All four trigger points |
| Cost | Higher; billed per request + duration |
Use cases: Token validation against DynamoDB or an auth service, image resizing on the fly (fetch, process, return), geolocation-based content personalization requiring an API call, dynamic HTML generation.
The Decision Rule
Do you need to make a network call (database, API, external service)?
YES → Lambda@Edge
NO → CloudFront Functions (faster, cheaper, simpler)
A common mistake is using Lambda@Edge for simple header manipulation. This adds unnecessary cold-start latency and cost. Conversely, using CloudFront Functions for token validation against a database is impossible — it has no network access and will silently fail or error.