AWS Builder Center

Lambda grew up and moved out of the handler

Lambda now has Event Functions, Web Functions, Durable Functions, MicroVMs and Managed Instances. Here's how each one retires a workaround developers built for the classic event handler, and how to pick the right shape for your workload.

Series: Serverless (2 articles)

  1. 1
    Lambda grew up and moved out of the handler This article
Based on my talk at  AWS Community Day Johannesburg , 30 October 2026.

For a long time, Lambda lived by a simple house rule: an event comes in, your function runs, and it's done within 15 minutes. That rule served it well. But when a workload didn't fit, developers had to bend their code around the handler, or take the workload somewhere else.
Over the past year, Lambda grew up. It can now listen on a port like any web server, wait up to a year for a workflow to finish, and hand each user their own VM to run code nobody has reviewed. The handler is still there, but it's no longer the only option.
This post walks through how Lambda got here, and the five workarounds you can stop building.

One shape, refined for twelve years

Since  Lambda launched in 2014 , it has had one shape: an event arrives, your function runs, and it returns.
Twelve years of launches made that shape better without changing it:
Every step removed a limit. The model stayed an event handler.

The promise vs the house rules

Growing up doesn't mean changing who you are. It means keeping your values and dropping the rules that only made sense when you were young.
Lambda is the same. Some things are the promise of serverless, and those haven't changed. Others were house rules that suited an event handler, and those are the ones Lambda has outgrown.
The promise (still true)
The house rules (outgrown)
No infrastructure to manage
One request per execution environment
Automatic scaling
A 15-minute cap
Pay for use
Billing on wall-clock time
Strong isolation
A sandbox Lambda fully manages
The house rules were sensible for events from queues, streams and buckets. They kept Lambda simple to reason about. But not every workload lives by them, and when yours didn't, you built a workaround.

Five workarounds you may have built

Be honest: how many of these have you done?
  1. Added an adapter so a web framework could run inside a handler. ( I did .)
  1. Paid for the wait while a request sat on a database or API call.
  1. Moved steady, high-volume traffic to containers or EC2 for instance pricing.
  1. Split long jobs into pieces to fit inside 15 minutes.
  1. Ran untrusted code yourself, on self-managed Firecracker or EC2.
Each of these now has a first-party answer.

Lambda in 2026: form factors and capacity providers

The clearest way to think about Lambda today is two question:

Who manages the sandbox?
  • Lambda manages it: Event Functions (the functions you already know, renamed), Durable Functions (Event Functions plus an SDK for long-running workflows) and Web Functions (a standard HTTP server).
  • You manage it: MicroVMs (a VM sandbox whose lifecycle you control).

Where does it run?
  • On-demand: scales per request, down to zero.
  • Lambda Managed Instances: your functions on EC2 instances in your account, which Lambda launches, patches and terminates for you.
All of these sit on a common serverless foundation, with different lifecycles for different jobs.

Workarounds 1 and 2: Web Functions

What if Lambda just listened on a port?
That's  Web Functions . You write a normal Node.js HTTP server, and the only Lambda-specific line is reading the host and port Lambda gives you:
JavaScript
import express from 'express';

const app = express();
const [host, port] = (process.env.AWS_LAMBDA_HTTP_ENDPOINT || '127.0.0.1:3000').split(':');

app.get('/', (req, res) => res.json({ message: 'Hello from Lambda Web Functions!' }));

app.listen(Number(port), host);

Deploy it with one command:
Bash
aws lambda-web deploy --name my-web-app --code ./my-app

What you get:
  • No adapter. Express, Fastify and Hono run as they are, and the same file runs on your laptop.
  • Many requests per environment, so a burst of traffic shares warm environments instead of creating new ones.
  • Active CPU billing. CPU is billed only while your code is working, so time spent waiting on I/O costs little CPU. Memory and requests are billed separately.
  • Streaming built in. Because it's an ordinary HTTP server, every write reaches the client as it happens, whether that's Server-Sent Events, chunked NDJSON or plain text.
  • Multi-Region on one URL. Add  --regions  to the deploy command and requests route to the lowest-latency Region. Your compute is replicated; your data is still your design decision.
  • Built-in canary deploys using revision weights.
  • Node.js 24 on Arm64 at launch.

This closes a long loop. Aidan Steele  traces the history : community projects like his serverlessish ran web servers on Lambda back in 2020, then came the Lambda Web Adapter, and now it's a first-party feature. His post is also the best tour of what's inside a Web Function's environment. For working examples of REST, SSE, chunked streaming, gRPC-Web, webhooks and IAM auth, see Eric's post  Why I'm excited about AWS Lambda Web Functions  and its companion repo.

Streaming matters to me. Last year I wrote about  response streaming on AWS serverless , using API Gateway REST API, a Python Lambda function and Amazon Bedrock. To stream from Python, I had to package a FastAPI app with the Lambda Web Adapter. That is exactly workaround number 1. With Web Functions, a Node.js server streams with no adapter and no special handler. Python still isn't covered: Web Functions run Node.js only, and Event Functions only stream natively on Node.js managed runtimes. For Python, you still need the Web Adapter or a custom runtime, but the direction is clear.

The catch: no session affinity

Requests are spread across execution environments, so you can't keep per-user state in memory and expect the next request to find it.
Julian Wood showed a memorable answer by  running Doom on Web Functions : save the inputs, not the state. Because the game engine is deterministic, any environment can rebuild a game by replaying its input log from DynamoDB, with handoffs between environments of about 120 ms. The same idea works for any app whose state can be rebuilt from a log of what the user did. You can  play it yourself .

Workaround 3: Lambda Managed Instances

For steady, high-volume traffic, Managed Instances runs your Event Functions (Durable ones included) on EC2 instances in your account.
  • You choose the instance types, such as Graviton.
  • Lambda launches, patches and terminates the instances.
  • EC2 pricing applies, so Savings Plans and Reserved Instances count.
  • Each environment can handle many requests at once, so write your code to be safe under concurrency.
A good rule: On-demand for spikes, Managed Instances for steady lines.

Workaround 4: Durable Functions

Durable Functions add steps and waits to the handler you already write. Lambda checkpoints each step, suspends while you wait for a person or an event, and replays from the last checkpoint after a failure. Workflows can run for up to a year, and on On-demand you don't pay for compute while a workflow waits.
The short version: build like a monolith, deploy like microservices.

Workaround 5: Lambda MicroVMs

 MicroVMs  are for code the app's developer didn't write: AI agent sandboxes, notebooks, browser IDEs, CI runners and game servers. The  Compute Blog launch post  walks through a full example: a data-analytics notebook per analyst that suspends when idle and resumes where they left off.
  • VM isolation: each MicroVM has its own kernel and its own HTTPS endpoint, built from an ordinary Dockerfile.
  • Fast launch and resume: MicroVMs start from a snapshot of your initialised app, and can burst above their baseline size.
  • You control the lifecycle: launch, suspend, resume and terminate. Memory and disk are kept across suspend, for sessions of up to 8 hours.
  • Any port, over HTTP-based protocols, including HTTP/2, gRPC and WebSockets.

The key difference from Web Functions: with MicroVMs, your app decides when each environment exists and which user it belongs to.

Choosing the right shape

If your workload is…
Use
Events from SQS, S3 or streams
Event Functions
An HTTP app or API
Web Functions
Longer than 15 minutes, or waiting on people
Durable Functions
Untrusted code, with a VM per user or job
MicroVMs
Steady and high-volume
Run it on Managed Instances

What stays the same

  • Your existing functions don't change. Only the name does.
  • Multi-AZ, patched for you.
  • The same IAM, CloudWatch, SAM and CDK.

Takeaways

  1. Pick the shape that fits the workload, instead of bending the workload to fit Lambda.
  1. Know the new realities: no session affinity on Web Functions, an 8-hour lifespan for MicroVMs, and Node.js-only Web Functions for now.
  1. Help shape what's next: vote on the public roadmap at  github.com/aws/aws-lambda-roadmap .

Serverless set out to give developers their time back. With these launches, it gives that time back to a lot more workloads.

Further reading

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.

Series: Serverless (2 articles)

  1. 1
    Lambda grew up and moved out of the handler This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article