Skip to main content

About SpeedWorkers on CloudFront with Lambda@Edge

Overview

This section contains the Lambda@Edge deployment of SpeedWorkers for Amazon CloudFront. Use it when the routing logic must live in Lambda@Edge — typically because the distribution already runs Lambda@Edge functions on the viewer/origin events (CloudFront accepts a single function per event, and viewer events cannot mix CloudFront Functions with Lambda@Edge), or because the bot detection needs a full Node.js runtime (outbound HTTP calls, larger code).

Shared architecture

Both implementations share the same foundation:

  • The cache behavior targets an origin group: primary = SpeedWorkers, secondary = your true origin, failover on 403/500/502/503/504 (403 is the SpeedWorkers cache-miss signal).

  • A viewer-request lambda (viewer.mjs) runs on every request: it strips inbound x-sw-* headers, classifies the request bot/user (x-sw-request-type, part of the cache key to partition the cache), and saves the original host and user-agent. It is also the place to plug your own bot verification logic.

  • An origin-request lambda runs on cache misses: eligible bot GET/HEAD requests go to the origin group untouched (SpeedWorkers, with native failover to your origin); everything else must reach your origin without touching SpeedWorkers.

  • The behavior only allows GET/HEAD (CloudFront restriction on origin-group behaviors); routes receiving other methods live in dedicated behaviors placed before.

  • Error caching TTL must be 0 (the 403 failover signal must never be cached).

The two implementations differ only in how the origin-request lambda sends ineligible requests (users, ignored paths…) to your origin.

The two origin-request implementations

Redirect — origin.mjs

The lambda rewrites request.origin to your true origin, configured in the lambda code (swFallback* constants). CloudFront then calls your origin directly, bypassing the origin group.

Force fail — origin_force_fail.mjs

The lambda generates a 403 response, which matches the origin group's failover criteria: CloudFront retries the group's secondary origin (your true origin, configured in CloudFront only). The lambda is invoked a second time on that pass and lets the request through. Viewers never see the 403 unless the secondary origin itself is unreachable.

Choosing between the two

Redirect (origin.mjs)

Force fail (origin_force_fail.mjs)

Your origin's config

Duplicated in the lambda code (swFallback*) and in the origin group

In CloudFront only (origin group's secondary origin)

Origin change (domain, timeouts…)

Update the lambda and publish a new version and update the distribution

Update the origin group in CloudFront

Several origins / distributions

One lambda build per origin

One single origin-agnostic lambda for all

Origin-request invocations

1 per cache miss

1 for bots, 2 for every non-bot cache miss (forced failover ⇒ second pass)

Latency for users on cache miss

None added

One failover round trip added

Failure mode of a lambda bug

Falls back to the origin configured in the lambda

Forces the failover — no origin knowledge needed, but a broken secondary origin surfaces a 403 to viewers

Extra caveats

Doesn't work with the legacy "forward all headers" cache settings; forced failover only works for GET/HEAD(/OPTIONS)

Rule of thumb: Prefer redirect when the deployment targets one distribution with one stable origin and you care about user-facing latency and lambda cost — the common case. Prefer force fail when the same lambda must serve several origins or distributions, or when the team managing CloudFront must be able to change the origin without touching lambda code.

Both variants can be mixed freely with the shared viewer.mjs: switching from one to the other is just swapping the origin-request association (and its configuration).

Documentation

Other CloudFront deployments of SpeedWorkers live outside this section: the CloudFront Function deployment (modules/cloudfront/function.js, viewer-request origin-group creation at runtime — the only option for VPC origins, and suited to behaviors that must accept all HTTP methods) and the LWCDN deployment (modules/cloudfront/lwcdn/, fallback handled by the SpeedWorkers endpoint itself, no origin group — also compatible with all-methods behaviors).

Did this answer your question?