AWS Lambda@Edge vs Cloudflare Workers: Edge Compute Playbook
Lambda@Edge and Cloudflare Workers sell the same promise — code that runs at the edge, close to the viewer — and charge for it in different currencies. Lambda@Edge bills requests plus GB-seconds, from a function that must live in us-east-1 and is replicated to CloudFront edge locations. Workers bills requests plus CPU milliseconds, from V8 isolates, with no charge for wall-clock duration. This playbook answers the four questions that decide real architectures from the vendors' own pricing and limits pages, then prices both at 10M, 50M and 100M requests a month.
Two runtimes, two billing meters
Lambda@Edge is a feature of Amazon CloudFront. You attach a numbered Lambda version to a distribution at one of four triggers: viewer request, viewer response, origin request, origin response. The meter has two parts: requests at $0.60 per million, and duration per GB-second, metered at 1 ms granularity. The pricing page states duration as $0.00000625125 per 128MB-second — $0.00005001 per GB-second. Memory runs 128 MB to 10,240 MB, CPU power in proportion: at 1,769 MB a function has one vCPU equivalent.
Workers runs a different execution model. A Worker is JavaScript, TypeScript, Python, or Rust code inside a V8 isolate — a lightweight sandboxed context, not a container or virtual machine. One isolate handles many concurrent requests, capped at 128 MB of memory, heap plus WebAssembly allocations. Its meter also has two parts, but neither is wall-clock duration: requests per million above the included allotment, and CPU time per million CPU-milliseconds above its allotment. Waiting on network requests does not count toward CPU time. The limits page puts the average Worker at approximately 2.2 ms of CPU per request; heavier workloads use 10 to 20 ms. The two platforms tax different sins: Lambda@Edge taxes wall-clock time, so a 200 ms origin wait is billed; Workers taxes CPU only, so the same wait is free.
The comparison table
| Dimension | Lambda@Edge | Cloudflare Workers | Authority |
|---|---|---|---|
| Request price | $0.60 per 1M requests | $0.30 per 1M above 10M included | AWS; Cloudflare pricing |
| Compute price | $0.00005001 per GB-second | $0.02 per 1M CPU-ms above 30M included | AWS; Cloudflare pricing |
| Monthly floor | None; charged from request one | $5.00 per month minimum (Paid) | AWS; Cloudflare pricing |
| Free tier | Not confirmed | 100,000 requests per day; 10 ms CPU per invocation | Cloudflare Workers pricing |
| Execution model | Lambda function replicated to edge locations | V8 isolate; one isolate serves many requests | AWS docs; Cloudflare limits |
| Memory | 128 MB to 10,240 MB; 1,769 MB ≈ 1 vCPU | 128 MB per isolate, heap plus WebAssembly | AWS quotas; Cloudflare limits |
| Timeout | 30 seconds | 5 min CPU per invocation, default 30 s | AWS quotas; Cloudflare limits |
| Response size | 40 KB viewer-triggered; 1 MB origin-triggered | No equivalent published cap | AWS quotas |
| Package size | 50 MB compressed, function plus libraries | 64 MiB Worker size | AWS quotas; Cloudflare limits |
| Throughput quota | 10,000 requests per second per region; up to 10 per instance | 50 subrequests per request (Free); 10,000 (Paid) | AWS quotas; Cloudflare limits |
| Runtimes | Latest Node.js and Python only | JavaScript, TypeScript, Python, Rust (beta) | AWS restrictions; Cloudflare docs |
| Deployment constraint | Function must be in us-east-1; numbered version only, never $LATEST | Wrangler or dashboard deploy; 100 free, 500 paid | AWS restrictions; Cloudflare limits |
Request pricing, read off the vendor pages
The request charges look close until the included allotments are applied. Lambda@Edge charges $0.60 per million requests with no included requests in its worked example: 10 million executions at 10 ms each bill $6.00 for requests and $0.63 for compute, $6.63 in total. Workers Paid charges $5.00 a month, includes 10 million requests and 30 million CPU-milliseconds, then $0.30 and $0.02 per additional million requests and CPU-milliseconds. The Free plan allows 100,000 requests a day — about 3 million a month — at 10 ms of CPU per invocation.
Two subtleties change the arithmetic. Workers does not bill for subrequests: a Worker calling an origin, KV, or D1 pays for the inbound request only. Workers bills cache hits at the same per-request rate as invocations, but cache hits consume no CPU time — so an 80 percent hit rate cuts the CPU bill while leaving the request bill untouched. Cloudflare's Example 5: the same Worker drops from $45.40 to $34.20 a month at an 80 percent cache-hit rate. Neither vendor charges for egress on this path.
Cold start: the model, not a millisecond
Neither vendor publishes a comparable cold-start figure, and this playbook prints none. What the docs publish is the shape of each model. A Lambda@Edge cold start spins up a Lambda execution environment: runtime initialises, 50 MB package loads, handler runs. Concurrency is regional and shared with all Lambda functions in the region; each instance serves up to 10 requests per second, and the per-region quota is 10,000 per second. The function must be created in us-east-1 — every version starts there and replicates outward.
A Workers cold start is a new V8 isolate, and the limits page bounds it rather than timing it: worker startup time is listed at 1 second, and the average Worker consumes about 2.2 ms of CPU per request. An isolate that exceeds 128 MB lets in-flight requests finish while new requests get a fresh isolate. There is no regional concurrency quota to manage and no home region to deploy from. The honest statement is directional: isolates start lighter than execution environments — but no number here quantifies the gap, because no vendor page opened this cycle does. That gap matters most on viewer-request triggers, which run on every request: their cold-start behaviour is the p95 latency behaviour. The stale-while-revalidate and edge purge playbook covers how cache policy interacts with these triggers.
Runtime limits that decide the architecture
Limits, not prices, veto most migrations. Lambda@Edge caps the compressed package at 50 MB including libraries, a viewer-triggered response at 40 KB including headers and body, and an origin-triggered response at 1 MB, with a 30-second timeout. Only the latest Node.js and Python runtimes are supported, the function must be a numbered version — $LATEST and aliases are refused — and several Lambda features are unavailable: VPC access, provisioned concurrency, dead letter queues, layers, arm64, container images, and X-Ray. A viewer-response function cannot modify the HTTP status code, and CloudFront-added headers are invisible to viewer-request functions; only origin triggers see them.
Workers caps memory at 128 MB per isolate, the Worker at 64 MiB, subrequests at 50 per request on Free and 10,000 on Paid, and simultaneous outgoing connections at 6 per request. CPU time per invocation is 10 ms on Free and up to 5 minutes on Paid, defaulting to 30 seconds, with 15 minutes for Cron Triggers and Queue Consumers. There is no hard wall-clock limit for HTTP Workers: while the client stays connected the Worker can keep processing, and ctx.waitUntil extends execution up to 30 seconds after the response. Environment variables are capped at 64 per Worker on Free and 128 on Paid, at 5 KB each; the account holds 100 Workers on Free and 500 on Paid, with 5 Cron Triggers on Free and 250 on Paid. For the compute-only comparison against a different edge runtime, see the Workers vs Vercel playbook.
Monthly cost math: 10M, 50M and 100M requests
Stated profiles — Lambda@Edge runs 10 ms at 128 MB per request, the vendor's own worked-example duration; Workers runs 7 ms of CPU per request, the vendor's own example profile. Lambda@Edge charges $0.60 per million requests plus $0.00005001 per GB-second. Workers charges a $5.00 subscription, includes 10 million requests and 30 million CPU-milliseconds, then $0.30 and $0.02 per additional million requests and CPU-milliseconds.
\\text{Lambda@Edge per request} = 0.60 \\times 10^{-6} + 0.01 \\times 0.125 \\times 0.00005001 = 0.00000060 + 0.0000000625 = 0.0000006625 \\text{ dollars}
\\text{Lambda@Edge per million} = 0.6625 \\text{ dollars} \\approx \\$0.66
\\text{Workers marginal per million at 7 ms CPU} = 0.30 + 7 \\times 0.02 = 0.30 + 0.14 = 0.44 \\text{ dollars}
\\begin{aligned}
\\text{10M Lambda@Edge} &= 10 \\times 0.60 + 10{,}000{,}000 \\times 0.01 \\times 0.125 \\times 0.00005001 = 6.00 + 0.63 = \\$6.63 \\\\
\\text{10M Workers} &= 5.00 + 0 + (70{,}000{,}000 - 30{,}000{,}000) \\div 1{,}000{,}000 \\times 0.02 = 5.00 + 0.80 = \\$5.80 \\\\
\\text{50M Lambda@Edge} &= 50 \\times 0.60 + 62{,}500 \\times 0.00005001 = 30.00 + 3.13 = \\$33.13 \\\\
\\text{50M Workers} &= 5.00 + 40 \\times 0.30 + 320 \\times 0.02 = 5.00 + 12.00 + 6.40 = \\$23.40 \\\\
\\text{100M Lambda@Edge} &= 100 \\times 0.60 + 125{,}000 \\times 0.00005001 = 60.00 + 6.25 = \\$66.25 \\\\
\\text{100M Workers} &= 5.00 + 90 \\times 0.30 + 670 \\times 0.02 = 5.00 + 27.00 + 13.40 = \\$45.40
\\end{aligned}
The 10-million Lambda@Edge total reproduces the vendor's own worked example exactly, $6.63, and the 100-million Workers total reproduces Cloudflare's Example 4 exactly, $45.40.
The gap widens with volume — Workers is $0.83 cheaper at 10 million, $9.73 at 50 million, $20.85 at 100 million — because Lambda@Edge pays from the first request while Workers' $5.00 floor buys 10 million requests and 30 million CPU-milliseconds outright. Run the margin on your own numbers through the Business Profit Margin Calculator before treating these as your bill.
The more useful number is the flip point: the average CPU per request at which Workers stops being cheaper. At 10 million requests, Workers costs $4.40 plus $0.20 per millisecond of average CPU, meeting Lambda@Edge's $6.63 at about 11.2 ms. At 100 million, Workers costs $31.40 plus $2.00 per millisecond, meeting $66.25 at about 17.4 ms. Below those thresholds Workers wins on price; above them the CPU bill overtakes the request-charge advantage. A handler averaging 2.2 ms — the vendor's stated average — is nowhere near either threshold.
Scenario: Meridian Press prices a migration
Scenario: Meridian Press, a news publisher, serves 50 million edge requests a month through a viewer-request function that rewrites headers, enforces geo rules, and redirects legacy URLs — 10 ms of execution and 7 ms of CPU per request. On Lambda@Edge the month costs $33.13; on Workers it costs $23.40. The saving is $9.73 a month, $116.76 a year. Suppose the migration costs 24 engineer-hours at $75 an hour — $1,800 — to rewrite the handler and re-run the tests. Break-even is 185 months, about 15.4 years. The saving is real and the migration is still wrong on price alone. Meridian migrates anyway: its editors want geo rules deployed from Wrangler in minutes instead of a versioned Lambda publish replicated from us-east-1, and the Workers bill caps itself with a spending limit that blocks new invocations at a threshold. Cost decides nothing here; deploy speed and the spending cap decide everything.
Operator Boundaries
This playbook is for whoever chooses an edge compute platform: the staff engineer, the tech lead, or the founder paying the bill. It is written for teams already on CloudFront or Cloudflare, running a real edge function in production. Who must avoid each side: anyone needing VPC access, provisioned concurrency, or a runtime outside Node.js and Python must avoid Lambda@Edge; anyone averaging more than about 17 ms of CPU per request at high volume must price Workers against the flip-point math above; anyone whose response exceeds 40 KB on a viewer trigger must avoid Lambda@Edge for that trigger; anyone needing more than 128 MB of isolate memory must avoid Workers. Neither platform is a general compute replacement — a workload needing minutes of compute, large memory, or a private network belongs behind the edge, not on it.
Founder & CEO Insight — Enow A. Jovial
The switch, run as a checklist
- Read your handler's CPU profile first. Average CPU milliseconds per request from your own logs.
- Check the response size against the trigger. Viewer-triggered responses cap at 40 KB on Lambda@Edge.
- List the hard requirements. VPC access, provisioned concurrency, layers, arm64, runtimes outside Node.js and Python — any one vetoes it.
- Price the three volumes. Run the formulas here at 10M, 50M and 100M with your own CPU and duration numbers.
- Find your flip point. The CPU milliseconds per request where Workers stops being cheaper.
- Test cold start on your own traffic. A burst after ten idle minutes, p95 from your logs.
- Set the spending cap before the traffic arrives. Workers' spending limit blocks invocations at a threshold; set it on day one.
- Pilot on one trigger. Move the viewer-request handler first, compare the same three numbers.
The decision in advance
Pick the platform by the handler, not the headline rate. Workers for CPU-light handlers, where the $5.00 floor buys the first 10 million requests. Lambda@Edge where the stack is already CloudFront and the handler fits the 30-second timeout and the 40 KB viewer cap. Measure the CPU profile, check the response size, price the flip point — then decide.