Classic Lambda for events and heavy compute. Lambda Web Functions for HTTP business logic, once in your region. Workers at the edge, for waiting, spikes and real-time.
The short version
| If the logic… | Run it on |
|---|---|
| reacts to SQS, S3, EventBridge, Cognito or a schedule | Classic Lambda |
| needs heavy CPU, lots of memory, native modules or another language | Classic Lambda |
| is an HTTP API or web app that mostly waits on Postgres | Lambda Web Functions (once in your region), otherwise classic Lambda |
| sits in front of your backend: auth, rate limits, webhooks, streaming, spikes | Workers |
| needs WebSockets or live shared state | Workers + Durable Objects |
Move from Lambda to Web Functions when
- HTTP APIs behind function URLs mostly wait on Postgres: merge them into one Express or Hono app.
- Aurora connections run out: one environment shares one pool across up to 128 requests.
- Requests are slow. At 2,000 requests a second:
| Time per request | In flight | Web Functions | Classic Lambda |
|---|---|---|---|
| 100 ms | 200 | ~4 environments | 200 instances, fine |
| 500 ms | 1,000 | ~16 environments | At the 1,000 default |
| 1 s | 2,000 | ~32 environments | Throttled unless the quota is raised |
| 20 s (LLM stream) | 40,000 | ~313 environments | Far over the default |
Move a Worker to Web Functions when
- It grew into business logic that needs native modules, more than 128 MB or full Node.js.
- It calls AWS with stored keys: Web Functions get an IAM role.
- It needs a private VPC database, or compliance needs everything on the AWS bill.
Where Web Functions lose to Workers
WebSockets (not supported), spikes from zero (10,000 req/s per endpoint by default, and new environments must start), rarely-hit webhooks (scale to zero means a cold first request), global users (5 regions vs every Cloudflare location), huge bodies, and deliverables that must run for years without runtime upgrades.
Price comparison (USD a month, before free tiers)
| Scenario | Classic Lambda | Web Functions | Workers |
|---|---|---|---|
| REST API: 10M requests, 100 ms, 10 ms CPU | $8.67 | ~$8.72 | $6.40 |
| Same API at 1B requests | ~$867 | ~$600 | ~$501 |
| LLM streaming proxy: 1M chats × 20 s | $33.50–167 | ~$3.40 | ~$0 extra |
| Server-rendered app: 5M page views | $11 | ~$12 | ~$8.40 |
| PDF rendering: 100k × 8 s CPU | ~$21 | ~$22, blocks other requests | Not possible |
| Webhook hit 3× a month | ~$0 | ~$0 | ~$0 |
| Live auction (WebSockets) | ~$407 via API Gateway | Not supported | $15–30 with Durable Objects |
Rates: Lambda Arm $0.0000133334/GB-s and $0.20/M requests. Web Functions (Sydney price list, not launched) $0.0000279955/vCPU-s, $0.0000037065/GB-s, $0.30/M requests, assuming 300–500 MB in use and environments up all month. Workers $5 base including 10M requests and 30M CPU-ms, then $0.30/M and $0.02/M CPU-ms.
What the numbers say: for typical APIs, Web Functions cost about the same as Lambda; you migrate for the connection pool and the simpler app. At high volume they're about 30% cheaper. For long waits they're as cheap as Workers.