JSTGTECH
← Back to blog

Service spotlight: CloudFront Functions vs Lambda@Edge

3 min read

CloudFront gives you two different ways to run code at the edge, and they’re not tiers of the same thing — they’re built for genuinely different jobs, with different runtime models, different latency profiles, and a pricing gap wide enough that picking the wrong one for a simple task is a real cost mistake, not just a style preference.

The two options

CloudFront Functions runs a restricted subset of JavaScript in a lightweight, purpose-built runtime embedded directly in CloudFront’s edge locations — sub-millisecond execution, no cold starts, and it can run on viewer request/response events only (the events closest to the end user, before/after CloudFront’s cache). It has hard constraints: no network access, no filesystem access, a 10 KB code size limit at the “basic” compute tier (2 MB on the newer “advanced” tier, which raised limits and added things like key-value store access), and a 1 MB max HTTP request/response size to operate on.

Lambda@Edge runs actual Lambda functions (Node.js or Python, your choice of runtime and package) at CloudFront edge locations, and can run on all four CloudFront event types — viewer request, origin request, origin response, and viewer response — with network access, larger code packages, and access to other AWS services from within the function. It has real cold starts (worse than standard Lambda, since it’s replicating across edge regions) and materially higher per-invocation and per-GB-second pricing than CloudFront Functions.

Picking based on the job, not the label

The deciding question isn’t “which is more powerful” — Lambda@Edge always wins that comparison — it’s **does this task need origin access or first-party AWS service calls**. If the answer is no, CloudFront Functions is almost always the right choice:

  • URL rewrites and redirects (the trailing-slash/index.html rewrite pattern static sites need for pretty URLs) — pure string manipulation on the request, no origin needed. CloudFront Functions territory, and meaningfully cheaper and faster than Lambda@Edge for exactly this job.
  • Header manipulation — adding security headers, normalizing a header for cache-key purposes, stripping a header before it hits the origin. Same story: no origin call needed, CloudFront Functions handles it at a fraction of the cost.
  • A/B testing via cookie-based routing, viewer-side auth token ** validation** (checking a JWT’s signature without calling out to a service) — still viewer-request/response only, still fits.

Reach for Lambda@Edge only when the task genuinely needs something CloudFront Functions structurally can’t do:

  • Calling another AWS service or an external API from inside the function (looking up a value in DynamoDB to decide which origin to route to) — CloudFront Functions has no network access at all, full stop.
  • Modifying the origin request/response, not just the viewer-facing side — e.g., rewriting the request CloudFront sends to a custom origin based on logic too complex for a viewer-request rewrite alone.
  • Larger dependencies or non-JS runtimes — image manipulation libraries, anything needing Python or a sizable npm dependency tree that won’t fit CloudFront Functions’ size ceiling.

The pricing and latency gap

CloudFront Functions is priced per invocation, at a rate roughly two orders of magnitude cheaper than Lambda@Edge’s per-invocation-plus-duration pricing, and it runs with no cold start because it’s not a full Lambda execution environment being spun up — it’s closer to a purpose-built string- processing VM than a general compute runtime. For a function firing on every single request to a high-traffic distribution (which URL-rewrite and header functions typically do), that pricing gap is not academic — running a basic redirect rule as Lambda@Edge instead of a CloudFront Function on a busy site can be the difference between a rounding-error cost and a noticeable line item.

A practical tip

Default to CloudFront Functions and only reach for Lambda@Edge when you hit one of its actual constraints (no network access, code size, event type) — not the other way around. It’s easy to reach for Lambda@Edge out of familiarity with Lambda generally, but for the viewer-request rewrite and header-manipulation jobs that make up most CloudFront edge-compute use cases, it’s strictly worse on both cost and latency for no functional gain.

Related posts