· cloudflare / aws / serverless

Cloudflare Workers vs AWS Lambda: Serverless in 2026

Workers wins for global I/O-bound APIs. Lambda still owns CPU-heavy jobs, long timeouts, and teams already deep in AWS. Here is exactly where each one breaks.

By Ethan

2,289 words · 12 min read

Use Cloudflare Workers if you’re building a globally-served API where cold start latency shows up in your p99. Use AWS Lambda if you need more than 128 MB of memory, a timeout longer than 30 seconds of CPU time, or you’re already wired deep into AWS services like RDS, SQS, or Step Functions.

The cold-start gap has widened enough in 2026 that it’s no longer a genuine trade-off — it’s a constraint. What you’re actually deciding is whether Cloudflare’s ecosystem covers what you need.

Who this is for

Engineers choosing a serverless runtime for a new API or considering a migration off Lambda. If you’re already on Workers and happy, this post won’t change your mind. If you’re Lambda-first and wondering whether Workers is overhyped, keep reading.

What we tested

Numbers in this article come from the Rebal AI production case study (March 2026) — a Node.js 20 image annotation API running 2.3M requests/month peak — and from the Lambda cold-start benchmark tracker maintained by Maxime David, updated daily. Pricing math uses official figures from Cloudflare’s pricing page and AWS Lambda pricing as of May 2026. Where I cite a specific number, the link is in the sentence.

The fundamental difference: isolates vs containers

Lambda runs your code inside a Firecracker MicroVM or container. Each cold start goes through two billed phases (since August 1, 2025, INIT is billed at the same GB-seconds rate as INVOKE): INIT — download code, start runtime, run static initializers — then INVOKE. The INIT phase alone for Node.js 20 costs 200–350 ms at p50. Java 21 without SnapStart: 1–3 seconds at p50.

Workers uses V8 isolates — the same engine as Chrome, but stripped of a process boundary. Each Worker is a sandboxed JavaScript context sharing a single OS process with thousands of other isolates. No VM boot, no container pull, no OS init. The isolate loads in under 5 ms from cold.

There’s a trick that makes the cold start number essentially irrelevant in practice: when a client opens an HTTPS connection and sends the ClientHello (which includes the hostname via SNI), Cloudflare uses that moment to pre-load the Worker. By the time the TLS handshake completes — two round-trips from client to Cloudflare edge — the Worker is already warm. Since Workers load in under 5 ms and any real-world client-to-Cloudflare RTT is longer, the cold start experienced by the request is zero. Cloudflare’s own post on this explains the mechanism in full.

The caveat: this optimization only applies at the root hostname. Path-based routing for sub-path Workers doesn’t benefit.

Cold starts: the real story in 2026

Before August 2025, Lambda cold starts were a latency problem. Since August 1, 2025, they’re also a cost problem — AWS now bills INIT phase duration at the same GB-seconds rate as INVOKE. A 1-second cold start on a 256 MB Node.js function costs about 0.256 × 1 × $0.0000166667 = $0.0000043 per cold start. That’s trivial per event, but it adds up at scale, and the psychological cost is the same: your users hit a 400 ms spike, and you pay for the privilege.

Lambda cold-start p50 by runtime, based on current benchmark data:

Runtimep50 cold startp99 cold start
Node.js 20200–350 ms1.2–2.8 s
Python 3.12200–400 ms2.1–3.5 s
Java 21 (no SnapStart)1–3 s4–7 s
Java 21 (SnapStart)90–140 ms~780 ms
Go50–100 ms<200 ms
Rust (provided.al2023, arm64)12–22 ms<50 ms

Provisioned Concurrency eliminates cold starts but you pay for idle capacity: $0.0000041667 per GB-second of uptime, regardless of traffic. A 256 MB function held warm around the clock costs about $27/month per concurrent instance, before any request charges. At 10 concurrent instances: ~$270/month on top of normal Lambda costs — solely to keep instances warm.

Workers’ cold start: 2–5 ms overhead when the TLS trick can’t pre-load, zero when it can. No provisioned concurrency concept, no idle cost.

Latency at the edge: 300 PoPs vs one region

Every Workers deployment goes to 300+ cities simultaneously. There is no “pick a region” step. In the Rebal AI production case study, p99 cold-start overhead from a warm Worker was 2–5 ms globally — effectively the floor, since Cloudflare pre-loads the isolate during the TLS handshake at the nearest PoP.

Lambda lives in one region. A user in Southeast Asia hitting a us-east-1 function sees the full transatlantic round-trip plus function execution time. Lambda@Edge runs at CloudFront PoPs, but with drastically reduced limits: 5-second timeout for viewer-facing functions, 1 MB deployment package, 128 MB memory. The Rebal AI engineers observed 400–600 ms cold starts on standard Lambda@Edge at Southeast Asian PoPs — this was without Provisioned Concurrency. With Provisioned Concurrency on their most latency-sensitive functions, their overall service p99 dropped to ~18 ms — but that aggregate is dominated by their primary US user base. The geographic placement issue remained: provisioned instances lived in us-east-1, not at the edge PoP, so Southeast Asian requests still crossed a long haul regardless.

Lambda in a co-located region with Provisioned Concurrency is genuinely fast. The math only works if your users are concentrated in one region and you can absorb the Provisioned Concurrency bill.

What you’ll actually pay

The critical difference: Workers bills CPU time only. Lambda bills wall-clock time including I/O wait.

An I/O-bound function that spends 95 ms waiting on a database and 5 ms executing code costs Lambda 100 ms × memory allocation × rate. Workers charges for 5 ms. At high volume, that gap is the story.

Pricing comparison at a 256 MB equivalent workload, Node.js, 100 ms wall-clock execution, 5 ms CPU time:

Monthly volumeAWS LambdaCloudflare WorkersWinner
10M requests~$1.80~$5.40Lambda
100M requests~$55.80~$41.40Workers
1B requests~$626~$401Workers

Lambda wins at low volume because of its 1M free requests and 400,000 GB-seconds free duration. Workers’ $5/month base fee hurts at 10M requests.

The crossover is roughly 50–60M requests/month for a typical I/O-bound API. Below that, Lambda is cheaper. Above that, Workers pulls ahead — and the gap widens as CPU time shrinks relative to wall-clock time.

Flip the workload to CPU-heavy (image processing, SSR, ML inference — 50 ms actual CPU per 100 ms request): Workers CPU overage at 100M requests jumps to ~$97 extra, pushing Workers to ~$132/month. Lambda stays at ~$55.80 because wall-clock ≈ CPU time and the billing rates are similar. Lambda wins when CPU% of wall-clock is high.

Egress matters too: R2 (Cloudflare’s object storage) has zero egress fees when serving via Workers. S3 + CloudFront does not. If you serve many large assets through your functions, that gap is significant.

Developer experience: Wrangler vs SAM/CDK

Wrangler is a single CLI for init, dev, deploy, tail logs, and type generation. wrangler dev runs Miniflare locally — a full offline emulator for KV, Durable Objects, R2, and Queues. No Docker required, no AWS account credentials for local dev. TypeScript works out of the box; wrangler types generates runtime-accurate type definitions against your compatibility date.

The Lambda tooling landscape has three serious options:

  • AWS SAM: YAML-based, tight AWS integration. sam local invoke runs Lambda in a Docker container. Accurate but slower and Docker-dependent.
  • CDK (TypeScript, Python, Java): Express complex infrastructure as code. Steeper initial learning curve. Needs SAM CLI for any local Lambda emulation.
  • Serverless Framework v4: The most mature option, 1,000+ community plugins, cloud-agnostic by design. Version 4 introduced a paid tier for teams; the open-source story is fraying.

The real IAM tax on Lambda: every function needs an execution role with explicit grants to S3, DynamoDB, RDS Proxy, CloudWatch, etc. Workers has no IAM layer. That’s a genuinely different cognitive load on smaller teams.

Ecosystem: R2/D1/Durable Objects vs S3/DynamoDB/Step Functions

Cloudflare’s storage ecosystem has grown substantially, but it’s younger:

Workers serviceWhat it doesLock-in
KVEdge key-value, eventual consistencyMedium
R2S3-compatible object storage, no egressLow
D1SQLite over HTTPHigh — Cloudflare-only
Durable ObjectsGlobally unique stateful actorsHigh — proprietary
QueuesAsync message processingMedium
HyperdriveHTTP proxy to external PostgreSQL/MySQLLow

The D1 gotcha: Workers can’t open TCP connections. No pg driver, no raw PostgreSQL. You either use D1 (SQLite over HTTP), Hyperdrive (HTTP proxy to a connection pooler), or an HTTP-based ORM. If your team runs PostgreSQL and wants real TCP access, Lambda + RDS Proxy is the less painful path. If the database engine choice is still open, Postgres vs MySQL covers the key tradeoffs between the two dominant options.

Durable Objects are a genuinely novel primitive — globally unique actors with consistent state, no equivalent in Lambda. Real-time collaboration tools, distributed rate limiters, game state: if that’s your workload, Workers is the right choice; Lambda has no equivalent primitive.

Lambda’s AWS ecosystem breadth is larger: Step Functions for workflow orchestration, EventBridge for event routing, SQS and SNS for pub/sub, RDS Proxy for real TCP database connections. If you’re already on AWS and the surrounding services matter, migrating to Workers means either replicating those integrations or moving off them. If you’re weighing a managed backend platform as an alternative to assembling AWS services yourself, Supabase vs Firebase is the closest comparison.

VPC cold starts on Lambda, worth a note: AWS introduced Hyperplane ENIs in 2019 to eliminate per-function ENI attachment delays. The old 10-second VPC cold start is gone. The current overhead is substantially lower — still a factor to measure for your specific VPC configuration, no longer a dealbreaker.

The hard limits that will bite you

Workers limits that surprise Lambda veterans:

  1. 128 MB memory, fixed. Lambda scales to 10 GB; Workers cannot be allocated more. Image processing, PDF rendering, ML inference at scale — if your function needs more than 128 MB, Workers is the wrong choice, full stop.

  2. No Node.js stdlib by default. Workers use the V8 runtime, not Node.js. You need nodejs_compat in wrangler.toml to get most core modules. Still missing: net.createServer() (no TCP servers), fs.watch(), glob APIs. If you’re evaluating alternative JavaScript runtimes with better module compatibility, Bun vs Node.js compares the two most popular options.

  3. No persistent connections. The isolate model means no TCP connection pool between requests. A PostgreSQL pg.Pool doesn’t work. Every request is fully stateless from the connection perspective.

  4. 30-second CPU limit (Paid plan Unbound Workers). Free plan: 10 ms. If your function needs more than 30 seconds of CPU time — not wall-clock, CPU — you need Lambda.

  5. 10 MB bundle limit after gzip on Paid plan. Lambda allows 250 MB unzipped. Large vendored dependencies can push you over.

Lambda limits that surprise Workers veterans:

  1. Cold starts are a real operational concern — especially for Java/.NET and VPC-attached functions. With INIT now billed since August 2025, every cold start is both a performance and cost event.

  2. Lambda@Edge ≠ Lambda at the API level. The limits are drastically different (5 s timeout, 128 MB memory, 1 MB package). Mistakes here surface as bizarre regional failures in production.

  3. IAM is not optional. Every cross-service call needs an explicit IAM policy. For solo devs or small teams, this is a consistent tax.

  4. Payload caps: 6 MB synchronous response limit. If you’re proxying large files through Lambda, you’ll hit this.

Verdict: Cloudflare Workers vs AWS Lambda

Use Cloudflare Workers if:

  • Your users are globally distributed and p99 latency matters
  • The workload is I/O-bound (database reads, external API calls, content assembly)
  • Volume exceeds 50–60M requests/month
  • You want stateful coordination via Durable Objects
  • You want zero cold starts without a Provisioned Concurrency bill

Use AWS Lambda if:

  • Your function needs more than 128 MB of memory
  • Your job runs longer than 30 seconds of CPU time
  • You’re already using AWS-native integrations (RDS, SQS, Step Functions)
  • Volume is under 50M requests/month and you want the free tier math to work
  • Your team’s muscle memory is AWS and the IAM tax is acceptable

For monitoring either platform, Sentry and Datadog both have solid integrations — Sentry’s error tracking works well for Workers (their Cloudflare SDK handles the non-Node.js environment correctly), and Datadog’s Lambda layer is the standard choice for Lambda APM.

Caveats

The pricing math assumes an I/O-bound function with 5 ms CPU per 100 ms wall-clock. CPU-heavy workloads flip the Lambda vs. Workers cost comparison. Benchmark data for Workers comes from one production case study (Rebal AI, March 2026); Workers cold-start benchmark data from Cloudflare’s own engineering blog. Lambda benchmark data from the public lambda-perf tracker plus Maxime David’s methodology.

Affiliate disclosure applies to Sentry and Datadog links above; they had no involvement in this comparison.

References

  1. How Workers works — Cloudflare docs
  2. Eliminating cold starts with Cloudflare Workers — Cloudflare blog
  3. Cloudflare Workers pricing (official)
  4. Cloudflare Workers limits (official)
  5. Node.js compatibility in Workers — 2025 year review
  6. AWS Lambda pricing (official)
  7. AWS Lambda quotas (official)
  8. AWS Lambda execution environment lifecycle
  9. Lambda cold-start benchmark tracker (maxday.github.io)
  10. Cloudflare Workers vs AWS Lambda: six months of production reality — Rebal AI, Mar 2026
  11. Cloudflare Workers vs AWS Lambda cost — Vantage
  12. Serverless performance: Workers, Lambda and Lambda@Edge — Cloudflare blog