Announced 12 October 2026, and I'm already putting it in the stack because it changes how I'd write HTTP logic on AWS: one ordinary Express or Hono server instead of a swarm of tiny functions, with a shared database pool and billing that barely charges for waiting.
For typical APIs it costs about the same as classic Lambda; at a billion requests a month it's roughly 30% cheaper, and for long waits like LLM streaming it's as cheap as Workers. The reason to migrate isn't the price. It's the connection pool and the simpler app.
The big warning: it isn't in Sydney. Until it is, it's for workloads whose users and data sit in a launch region.
Use it when
- HTTP APIs and server-rendered apps that mostly wait on Postgres: merge many small Lambdas into one Express or Hono app.
- Database connection pain: one environment shares one connection pool across up to 128 requests, instead of one connection per Lambda instance. This can remove the need for RDS Proxy.
- Streaming responses (LLM chat, server-sent events) when you want them on AWS.
- You want plain
node server.jslocally and code you can move anywhere. - Slow requests: 2,000 req/s at 1 s each needs about 32 environments here, but 2,000 Lambda instances (over the default quota).
Don't use it when
- Your users or data are in a region it hasn't reached (Sydney, today): every database query would cross an ocean.
- Anything event-driven: it's HTTP only (no SQS, S3, EventBridge or Cognito triggers).
- WebSockets: not supported (the Upgrade header is stripped).
- Heavy CPU per request: one heavy request slows every other request in the same environment.
- Flash sales above 10,000 req/s: that's the default per-endpoint cap.
Pricing
$0.30 per million requests + $0.0000279955 per active vCPU-second + $0.0000037065 per GB-second of memory consumed while the environment lives (Sydney price-list rates; not launched there yet). Free tier: not stated.
Gotchas, with fixes
Gotcha: Up to 128 requests share one process. Lambda code that keeps the current user or tenant in a module-level variable becomes a data leak between users.
Fix: Audit global variables before migrating. Keep per-request data in AsyncLocalStorage or pass it explicitly.
Gotcha: A brand-new Web Function starts with a conservative per-environment concurrency limit and learns the right one from traffic. Your first big burst uses more environments and cold-starts more.
Fix: Load-test before launch and judge by the second run. Lambda remembers what it learned, even after scaling to zero.
Gotcha: No minimum or reserved environments, and AWS doesn't publish how fast new ones are added. A burst faster than the spare headroom waits on cold starts, and over the limits requests get HTTP 429, not a queue.
Fix: Clients retry with backoff and jitter. For known spikes, put Workers in front.
Gotcha: Default limits per region: 10,000 req/s per endpoint, 100,000 per account, 2,000 vCPUs (1,000 environments).
Fix: Request increases ahead of growth, and set rateLimit on endpoints to protect Postgres.
Gotcha: Node.js 24 on Arm64 only, 2 GB and 2 vCPU per environment.
Fix: Keep anything bigger on classic Lambda.
Provisioning
Pulumi aws-native only · No Terraform provider
Only @pulumi/aws-native (≥ v1.82.0): lambda.WebFunction, WebFunctionEndpoint, WebFunctionRevision, NetworkConnector. Not in @pulumi/aws yet (Terraform provider issue #50429 is open).
Instead, consider
- AWS Lambda Events, heavy compute, other languages, and regions it hasn't reached.
- Cloudflare Workers WebSockets, spikes from zero, global users, rarely-hit webhooks, huge bodies.
Worked examples
Where it fits
- An API for my app: Pick 03.
Once it's in your region, move HTTP logic to one Express app with a shared connection pool.
Sources
Last reviewed by Nicolas Dao