
AWS Lambda Web Functions Are Out. Here’s What Changes for Hono.
I built a Hono API with DynamoDB and compared three AWS hosting options. Here's how Web Functions handle requests, what my latency tests showed, and where I'd use them.
I already had a small Hono API on AWS. In my earlier post , I ran it with API Gateway + Lambda and with Bun on ECS/Fargate.
On October 12, AWS announced Lambda Web Functions . The launch lets Node.js HTTP servers handle concurrent requests inside Lambda, with active CPU billing and a managed HTTPS endpoint. I wanted to try that with an API that waits on a database.
So I built a reading list with Hono and DynamoDB. I could save a documentation link, list saved links, and mark one read.
The question was simple:
What does running a normal HTTP server inside Lambda give me that my usual Lambda setup does not?
I tested the app in Tokyo and checked its database records. Then I compared health checks and database reads across Web Functions, API Gateway + Lambda, and ECS/Fargate. The working code includes the deployment instructions.
The App I Built
The reading list has three authenticated routes:
| Request | What Happens |
|---|---|
POST /bookmarks | Check the title and URL, then save a link |
GET /bookmarks | List unexpired links with a cursor for the next page |
PATCH /bookmarks/{id}/read | Mark an existing link read |
I tested all three on the deployed API and read a saved record directly from DynamoDB. Missing or wrong tokens returned
401. Invalid input returned 400, and updating a missing bookmark returned 404.I also opened the API docs in Scalar:

This screenshot shows the API docs. I verified saving, listing, and marking a link read separately through HTTP requests.
Saving a link means waiting for a database response. I wanted to understand what the server could do during that wait.
What the Architecture Actually Does

DynamoDB stores the reading list. Secrets Manager stores the demo token, and CloudWatch receives the logs.
When someone saves a link:
- The browser sends an HTTPS request to the Web Function endpoint. Lambda handles the TLS connection and forwards the request to my server.
- Hono checks the bearer token and validates the title and URL.
- Hono writes the record to DynamoDB, waits for the result, and returns
201.
The server does not fetch the submitted URL. It stores the URL as text.
There are four concepts behind that Lambda icon:
| Concept | Plain English |
|---|---|
| Web Function | The named application |
| Revision | A saved version of its code and settings |
| Endpoint | The HTTPS address and rules for routing requests |
| Execution environment | A running copy of the server |
A revision cannot be edited after creation. Updating the code or revision settings means creating another revision. The endpoint settings control which revision receives requests. In my update trials, the endpoint URL stayed the same while the serving code changed. I did not measure downtime during those updates. AWS revision guide
The endpoint manages HTTPS, so my Node.js server listens on the internal host and port that Lambda supplies. I do not configure a certificate in Hono. AWS endpoint guide
DynamoDB holds the records independently of the server. Lambda can remove a running environment without erasing the reading list. I keep only reusable clients and a short-lived token cache in process memory.
For this demo, AWS generates the shared token in Secrets Manager. Hono reads it at runtime and caches it for sixty seconds. I put the table name and secret's AWS identifier in the environment settings. The token stays in Secrets Manager.
This is still a single-owner POC. Before serving multiple users, I would add user login, access checks, and separate records for each user. Demo links expire from the API after twenty-four hours; DynamoDB deletes expired records later. I would not store real personal reading history here.
The Change I Care About: Handling Requests While Waiting
With my usual API Gateway + Lambda setup, API Gateway turns the HTTP request into a Lambda event. Hono's
hono/aws-lambda adapter translates that event for the app. The default Event Function environment handles one invocation at a time.Web Functions run the normal Node.js server instead. One running environment can have several HTTP requests in progress.
Here is an illustrative excerpt of the POC's save handler, expanded to show the database wait. I call the route schema
saveRoute here; the repo defines it inline with createRoute. Authentication middleware runs before this handler.1
2
3
4
5
router.openapi(saveRoute, async (c) => {
const input = c.req.valid('json')
const bookmark = await readingList!.store.create(input)
return c.json(bookmark, 201)
})c.req.valid('json') gives the handler the body already checked against its Zod schema. The store sends a DynamoDB PutCommand. At the await, this request pauses until DynamoDB replies. Node.js can use that time to start another request in the same process.For example, one person saves a link while another lists saved links. A Web Function environment can keep both requests in progress, within its concurrency limit. A default Event Function environment handles one invocation at a time. This explains the hosting model; my benchmark did not trace overlapping requests inside an environment.
What Hono Adds
Hono gives me routes, middleware, and a request context (
c). With @hono/zod-openapi, I use schemas to validate input and generate the OpenAPI document that Scalar displays. The save handler receives validated data instead of parsing and checking it again. Hono's Zod OpenAPI example .That is why I used Hono for this small API: short typed handlers, validation, and docs in the same app. My route code stays the same across the three hosting paths. The entry point changes between a Lambda event handler and an HTTP server.
Express and Fastify can also handle async database calls and run on Web Functions. Concurrent requests per Lambda environment are an AWS feature, not a Hono-only feature. This experiment compares hosting options with Hono held constant; it does not compare framework speed.
On Node.js, I still use
@hono/node-server to serve Hono's Fetch API app over HTTP. That is Hono's Node.js bridge, not a Lambda event translator. Web Functions removes the need for the separate hono/aws-lambda event entry point. Hono on Node.js A long synchronous calculation can still block Node.js's main JavaScript thread. Requests also share process memory, so I keep user data in request context rather than global variables. AWS runtime guide
The one-invocation rule here describes default Event Functions. Lambda Managed Instances have different concurrency behavior. Lambda concurrency
Scaling Is More Than Adding Another Server
Web Functions can handle more requests in an existing environment and add environments as traffic grows. Lambda adjusts a dynamic concurrency limit based on resource use. The maximum I configure is an upper bound, not a promise that every environment will always handle that many requests.
For this POC, I set:
| Setting | Value | Purpose |
|---|---|---|
| Maximum environments | 2 | Bound the number of running server copies |
| Maximum concurrent requests per environment | 16 | Bound requests in progress in each copy |
| Endpoint request rate | 100 RPS | Limit incoming requests per second |
| Request timeout | 10 seconds | Bound the duration of a request |
Two environments with sixteen requests each gives a configured ceiling of 32 concurrent requests. Actual capacity can be lower because of Lambda's dynamic limit and account quotas. AWS also documents brief environment-limit overshoot during some operational changes.
Concurrency counts requests in progress. RPS counts arriving requests per second. A slow database call keeps a request in progress for longer, even if few new requests arrive. These settings help bound load; they are not a spending guarantee or a throughput benchmark.
When there is no traffic, Lambda removes idle environments and scales to zero. A later request can wait for a new environment to start. Scale-to-zero does not remove cold starts. AWS scaling guide
Waiting Changes the Bill Too
With default Event Functions, time spent waiting for DynamoDB still counts toward invocation duration. The duration charge depends on configured memory.
Web Functions bill active CPU separately from consumed memory. A database wait uses little CPU. The memory charge continues while the environment exists, including time between requests. Requests and data transfer have charges too. AWS Lambda pricing
I would test this billing model for an API that waits on databases or other services. I would measure the bill before assuming a saving. I have not measured the reading list's cost across these three hosting options.
Three Ways I Could Host This API
The save-link feature stays the same. Hono handles the routes, and DynamoDB stores the records.
1. API Gateway + Lambda
API Gateway receives the request and invokes the Lambda handler with an event. My earlier Hono app used the small event adapter.
I would keep this setup when I want API Gateway's API-management features. HTTP APIs support JWT authorization. REST APIs offer API keys, usage plans, request validation, and a response cache. I would check the features of each API type before choosing. AWS's feature comparison
2. ECS + Fargate
I package the server in a container. ECS manages the containers, and Fargate provides the computing resources. In this setup, a load balancer receives requests and sends them to the containers.
I would choose ECS/Fargate for another runtime or a container image. It also gives me more control over the server and service. I still configure networking and how the service scales. AWS's ECS explanation
3. Lambda Web Functions
I run the normal Node.js server behind Lambda's HTTPS endpoint. Lambda manages the environments and scales them with traffic.
For a small Node.js HTTP API, I can avoid adding API Gateway or configuring an ECS service just to get the server online. I still own authentication, validation, database design, and application limits.
| Setup | How Hono Runs | Why I'd Choose It |
|---|---|---|
| API Gateway + Lambda | Event adapter; one invocation per environment at a time by default | API Gateway features |
| ECS + Fargate | HTTP server in a container | Container and runtime control |
| Web Functions | HTTP server with concurrent requests | Managed Node.js HTTP hosting |
I verified the full save/list/mark-read workflow on Web Functions. For the three-way benchmark below, I tested the same health and synthetic database-read routes across all three setups. Authentication and writes were outside that timed run.
Where the Announced Features Fit
AWS's launch covers HTTP APIs, webhooks, server-rendered apps, and streaming responses. Here is how I would use those features around this API, starting with what the POC already uses.
| Feature | Use in This POC |
|---|---|
| Native HTTP server and managed HTTPS | Hono receives requests through its Node.js server, without API Gateway |
| Concurrent requests per environment | Async DynamoDB calls can overlap; I configured a limit of 16 requests per environment |
| Active CPU billing | Database waits use little CPU; I have not measured cost savings |
| Automatic scaling to zero | Lambda can remove idle server copies between visits to a small reading-list app |
The announcement also shows ways to grow beyond this POC. I have not implemented these extensions:
| Feature | Where I'd Use It |
|---|---|
| Native HTTP streaming | Add an AI summary route that returns generated text as it arrives |
| Multi-Region routing | Serve users nearer to their Region, after deciding where their records live |
| Traffic weights between revisions | Send a small share of requests to a new API revision before switching everyone |
| CloudFront with origin access control | Serve a frontend through CloudFront and restrict the API origin to the distribution |
| VPC connectivity | Connect an API to a private database such as RDS |
Those are hosting features I can use with Hono or another supported Node.js framework. AWS launch announcement
Multi-Region routing replicates code and configuration, not my DynamoDB records. Its latency-based routing does not provide health-based failover. My POC uses
HomeRegion in Tokyo. AWS endpoint types CloudFront origin access control would restrict who can reach the origin. I would still need application login and authorization for each user's reading list.
For the AI summary idea, Hono could call Bedrock directly and stream the response. AgentCore would be a separate choice for hosting agents and tools. This POC invokes no models. AgentCore Runtime
At launch, Web Functions run Node.js 24 on ARM64. WebSocket upgrades are unsupported. For other runtimes or container images on Lambda, I would consider Lambda Web Adapter , which translates Lambda events into HTTP requests. AWS sample applications
What the Three-Way Benchmark Showed
I ran a new experiment on October 15, 2026 (Asia/Manila), with all three paths in Tokyo. Every server used Node.js 24.21.0 on ARM64 and the same Hono app code. The client used Node.js 24.19.0 on the same macOS Arm64 laptop.
I tested two workloads: the health route and a consistent DynamoDB query returning twenty synthetic records. All three queried the same isolated table. The database benchmark bypassed token authentication, so this measures the read path, not the full authenticated reading-list workflow. No bearer token was sent over HTTP.
I ran three rounds at client concurrency caps of 1, 8, and 16. Each phase had ten warm-up requests and 100 measured requests. Request starts were paced at up to 40 per second, with keep-alive enabled. I rotated the runtime order each round.
All 5,400 measured requests passed. To keep the table readable, I'm showing p95 for each workload. The full report includes p50 and p99 too.
These results pool three rounds at client concurrency cap 8: 300 requests per runtime per workload, with zero failures. The database read returns twenty synthetic records.
| Runtime | Health p95 | Database Read p95 |
|---|---|---|
| Web Functions (HTTPS) | 112.03 ms | 127.88 ms |
| API Gateway + Lambda (HTTPS) | 129.05 ms | 133.13 ms |
| ECS/Fargate + ALB (HTTP) | 104.93 ms | 82.12 ms |
p95 means 95% of successful measured requests finished within that time. Lower is better. Timings include the network request and full response-body read. ECS used HTTP; both Lambda paths used HTTPS. CPU and scaling settings also differed.
The full benchmark report includes the source, raw samples, compute settings, and remaining limits of this test. Deployment and cleanup instructions are in the repo README .
My Take
For me, the useful change is running a normal Hono server on Lambda with managed HTTPS and concurrent requests. I can keep the app familiar while AWS handles the server environments.
I would try Web Functions for small Node.js APIs, dashboard backends, and streaming HTTP apps. I would keep API Gateway for its API features. I would use ECS/Fargate when I need a container or a different runtime.
For this reading list, Hono gives me validated routes and API docs. Web Functions gives me managed HTTPS and a server that can handle other requests while a database call waits. That is the combination I wanted to test.
References
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article