DEV Community

ほうき星 for AWS Community Builders

Posted on Originally published at qiita.com

Exploring Lambda Web Functions with an SSE Demo

This article is a machine translation of the contents of the following URL, which I wrote in Japanese:

Lambda Web Functions を触ってみた 〜SSE で「1 環境が複数リクエストをさばく」様子を Event Functions と比べる〜 #AWS - Qiita

はじめに こんにちは、ほうき星 @H0ukiStar です。 2026 年 10 月 12 日に Lambda Web Functions が GA しました。コードが HTTP リクエストを直接受け取れる、新しいタイプの Lambda 関数です。 今回は、この L...

favicon qiita.com

Introduction

Hi, I'm Houkiboshi @H0ukiStar.

On October 12, 2026, Lambda Web Functions became generally available. It's a new type of Lambda function whose code can receive HTTP requests directly.

AWS Lambda announces Lambda Web Functions - AWS

Discover more about what's new at AWS with AWS Lambda announces Lambda Web Functions

favicon aws.amazon.com

In this article, I'll first give an overview of Lambda Web Functions, then use an SSE-based demo to compare how "a single environment handles multiple requests concurrently" against a traditional Lambda.

Note: This article is based on a talk I gave at JAWS-UG Sainokuni Saitama Branch #12, rewritten as an article.
Exploring Lambda Web Functions

What Are Lambda Web Functions?

Lambda Web Functions are a new kind of Lambda function whose code can receive HTTP requests directly. A lot of the hassle that used to come with running a web framework on Lambda is now gone.

Here are the key characteristics:

  • You can run Express / Hono / plain Node.js and others with no adapter, as-is
  • Deployment is a single command: aws lambda-web deploy
  • A single environment handles up to 128 (default 64) requests concurrently
  • The only runtime currently available is Node.js 24
  • The execution environment is currently fixed at Arm64 / 2 vCPU / 2 GB

Note: The runtime and execution environment specs are the GA-time specification and may change in future updates.
Check the official documentation for the latest support status.

On the application side, the only thing you need to be aware of is starting your HTTP server on the listen target that the runtime passes to you.

// The runtime passes the listen target via the environment variable AWS_LAMBDA_HTTP_ENDPOINT
const [host, port] = process.env.AWS_LAMBDA_HTTP_ENDPOINT.split(':');

// Just start an ordinary HTTP server using the listen target you received
app.listen(port, host);
Enter fullscreen mode Exit fullscreen mode

So all you do is write your usual web server and listen as-is, and it works.

Existing Lambda Renamed to "Event Functions"

Alongside the arrival of Lambda Web Functions, the traditional Lambda has been renamed to Event Functions (a name-only change; the behavior is unchanged).

Since traditional Lambda follows a model where it receives an event (a dictionary) and processes it, I personally find the naming fitting.

Previously, the Lambda Web Adapter would convert an event like the one below into an HTTP request.

export const handler = async (event) => {…}
Enter fullscreen mode Exit fullscreen mode
// Example event from a function URL (partially omitted)
{
  "requestContext": {
    "http": {
      "method": "GET",
      "path": "/"
    }
  },
  "rawPath": "/",
  "rawQueryString": "",
  "headers": {…},
  "isBase64Encoded": false
}
Enter fullscreen mode Exit fullscreen mode

With Web Functions, you no longer need to be aware of this kind of event conversion.

A Three-Component Architecture

Lambda Web Functions consist of three components. It's easier to understand by mapping them to Event Functions concepts.

Component Role Equivalent in Event Functions
Web Functions The top-level container that has a name and an Arn The function itself
Endpoint The entry point that routes HTTP traffic to a Revision Alias
Revision An immutable snapshot that holds code + configuration; increases with each deploy Function version

The fact that a Revision is an immutable snapshot that stacks up with each deploy is exactly the image of a function version.

Here's a diagram of how these three components relate to each other.

Web Functions / Endpoint / Revision architecture overview

Pricing

There are three billing elements.

  • Requests: $0.30 / 1M requests
  • Memory: $0.0000042688 / GB-second
  • Active vCPU: $0.0000322421 / vCPU-second

The key point is that you're billed for active CPU time. As a result, wait time for things like DB access, external API calls, and AI inference is not billed.

Note that this is specifically about CPU; memory behaves a bit differently. While CPU is billed only for the time it's active, it's worth keeping in mind that memory is billed continuously for as long as the execution environment exists, including the gaps between requests.

You pay for requests, the CPU time your code actively uses, and the memory consumed by each execution environment for as long as it runs.

AWS Lambda Pricing

favicon aws.amazon.com

For reference, the Event Functions pricing is as follows.

  • Requests: $0.20 / 1M requests
  • Memory: $0.0000133334 / GB-second

If you just line up the numbers, the Event Functions memory unit price (GB-second) looks higher than Web Functions, but this isn't a straightforward comparison. Event Functions use a pricing model where CPU and other resources are allocated in proportion to the amount of memory you assign, so the CPU cost is effectively included in the memory price. That means you can't make an apples-to-apples comparison based on memory unit price alone.

Warning: All of the above are reference prices for the Tokyo region, and additional data transfer costs and the like apply.
Always check the official pricing page for the latest and accurate pricing.

Trying Out Lambda Web Functions

This is the main topic of the article. Let's actually verify that "a single environment can process multiple requests."

This time I built a demo that observes multiple sustained connections using SSE (Server-Sent Events). It keeps the connections open and pushes "how many connections this environment is currently holding" from the server to the client every 2 seconds.

Demo observing concurrent connections via SSE

I prepared this for both Event Functions (Lambda Web Adapter setup) and Web Functions and compared their behavior.

The full set of sample code used in the demo is available in the repository below; please refer to it for details.

sample-aws-lambda-web-functions

AWS Lambda Web Functions と Event Functions(+ Lambda Web Adapter) を、SSE(Server-Sent Events)デモで比較するサンプルコードです。

「1 つの実行環境が複数リクエストを同時にさばけるか」を、同時接続を観測しながら見比べられます。

このリポジトリは、以下の記事で使用したサンプルコード一式です。 記事: Lambda Web Functions を触ってみた 〜SSE で「1 環境が複数リクエストをさばく」様子を Event Functions と比べる〜(Qiita)

何を確認できるか

同じ SSE デモを 2 つの方式で実装し、同時接続時の挙動を比較します。

  • Web Functions:instanceId が揃ったまま activeConnections が増える(= 1 環境が複数リクエストを相乗り)
  • Event Functions:接続ごとに instanceId が必ず別々になる(= 1 環境 = 1 リクエスト)

この差が、Web Functions の同時処理モデルの本質です。

ディレクトリ構成

ディレクトリ 方式 概要
web-functions-sse Lambda Web Functions アダプター不要。標準の Node.js HTTP サーバが AWS_LAMBDA_HTTP_ENDPOINT を読んで listen するだけ。aws lambda-web deploy でデプロイ
event-functions-web-adapter-sse Event Functions + Lambda Web Adapter 従来型 Lambda にアダプターをレイヤーとして足した構成。AWS SAM でデプロイ

どちらのサンプルも、以下の 3 エンドポイントを持つシンプルな作りです。

  • GET / … 接続状況を可視化するダッシュボード(ブラウザで開く)
  • GET /events … SSE ストリーム。2 秒ごとに instanceId と activeConnections を push
  • GET /status … 現在の instanceId / activeConnections を JSON で返す

使い方

各ディレクトリの README に、ローカル実行とデプロイの手順をまとめています。

おおまかな流れは次のとおりです。

  1. 片方のディレクトリに移動する
  2. ローカルで node index.js を起動して動作を確認する
  3. それぞれの方式でデプロイする(aws lambda-web deploy / sam deploy)
  4. ダッシュボードから接続を複数開き、instanceId と activeConnections の変化を見比べる

注意事項

Warning

どちらのサンプルもエンドポイントは…

Demo Setup

The repository has samples that implement the same SSE demo in two different ways.

Directory Approach Overview
web-functions-sse Lambda Web Functions No adapter. A standard Node.js HTTP server just reads AWS_LAMBDA_HTTP_ENDPOINT and listens. Deployed with aws lambda-web deploy
event-functions-web-adapter-sse Event Functions + Lambda Web Adapter A traditional Lambda with Lambda Web Adapter added as a layer. Deployed with AWS SAM

Both samples are simple, with the following three endpoints.

  • GET / … A dashboard that visualizes the connection status (open it in a browser)
  • GET /events … The SSE stream. Pushes instanceId and activeConnections every 2 seconds
  • GET /status … Returns the current instanceId / activeConnections as JSON

When you increase connections in parallel from the dashboard, with Web Functions you'll see the instanceId stay the same while activeConnections increases (i.e., one environment is shared), whereas with Event Functions the instanceId is always different for each connection (i.e., one environment = one request). This is the biggest difference between the two.

Warning: Both samples expose endpoints with no authentication, as a public configuration. Keep them to evaluation use, and delete them once you no longer need them.

The Event Functions Case

First, the demo with the traditional Event Functions (LWA). Here's what it looks like as I actually increase the connections.

Event Functions (LWA) demo

  • Concurrent connections per environment: 1
    • Connections opened in parallel always get entirely different instanceIds, and each environment's activeConnections is always 1
  • Maximum number of environments: The upper limit of requests it can handle concurrently depends on the account's concurrency

In other words, it's one request = one environment, and you can see that each additional connection spins up a separate environment.

The Web Functions Case

Next, the demo with Web Functions. When you increase connections the same way, you see different behavior from before.

Web Functions demo

  • Concurrent connections per environment: The Revision setting maxConcurrencyPerEnvironment becomes the maximum number of requests that can be accepted concurrently
    • In the demo it's set to 2, so each environment's activeConnections caps at 2, but you can confirm that a single environment handles multiple requests
  • Maximum number of environments: The Endpoint setting Maximum environments becomes the maximum number of environments
    • In the demo it's set to 2, so from the 5th connection onward, a 429 is returned

Note: What's returned in this demo is a 429 Too Many Requests, indicating that the concurrency limit has been reached. Separately, a 503 Service Unavailable may be returned when, for example, an environment hasn't started yet and can't take on the processing. When you implement retries on the client side, it's reassuring to distinguish and handle these two separately.

Whereas Event Functions had one environment per connection, with Web Functions a single environment can hold multiple connections together. That difference came through clearly.

Differences in Environment Lifecycle

If we organize this difference from the perspective of the environment lifecycle, it comes out like this.

  • Event Functions: One environment = one request
    • When multiple requests arrive simultaneously, environments cold-start up to the concurrency limit

Event Functions environment lifecycle (one environment = one request)

  • Web Functions: A single environment processes multiple requests concurrently
    • It can process a default of 64, up to a maximum of 128, concurrently
    • This reduces cold starts accordingly

Web Functions environment lifecycle (one environment processes multiple requests concurrently)

The image is that when requests spike, Event Functions spins up environment after environment to handle them, while Web Functions handles multiple requests together in a single environment.
As a result, cold starts occur less often.

Conclusion

This time, I introduced Lambda Web Functions through an overview and a comparison of concurrent connections via an SSE demo.

To summarize the key points:

  • A Lambda that listens for HTTP directly, removing the need for the Lambda Web Adapter that Event Functions used to require
  • A single environment can process multiple requests concurrently, reducing cold starts accordingly
  • Because billing is based on active CPU, it's resilient to I/O waits and pairs well with SSE / streaming workloads

In particular, the two points of "one environment can handle multiple requests" and "no billing during wait time" pair well with web applications and workloads that involve external APIs or AI inference. If you actually migrate your own application with aws lambda-web deploy, I think you'll find it interesting to feel the difference in behavior firsthand.

I hope this article helps when you try out Lambda Web Functions.

Top comments (0)