AWS Lambda
The Hono and Fastify adapters run your app on AWS Lambda, behind:
- an API Gateway REST API (payload v1);
- an API Gateway HTTP API or a Function URL (payload v2);
- an Application Load Balancer.
The routes are the same as on a server: only the entry point changes.
The handler
Both adapters provide createLambdaHandler(). It takes a function that creates the app.
With Hono
Use the main entry of the adapter, @dotpress/adapter-hono, not /node: it has no Node.js server, and keeps the bundle small.
With Fastify
The handler of Fastify sends the events to inject() of the instance, through @fastify/aws-lambda: the Fastify hooks and plugins apply.
How the handler behaves
- Lazy creation. The app is created at the first invocation (the cold start), and reused by the next invocations of the execution environment. Invocations received meanwhile wait for the same app. The
handlerexport stays synchronous: no top-levelawaitin the module. - Recoverable failures. When the app cannot be created (a missing secret, a database down), the error is logged, the invocation gets the standard
500error, and the next invocation tries again. - Buffered responses. Responses are sent once complete.
stream()works for finite streams; Server-Sent Events (sse()) are not supported. A stream that fails is never sent truncated: with Fastify, the invocation gets an empty500; with Hono, it fails, and API Gateway answers502. Lambda response streaming is not supported yet. - Binary responses are sent in base64: every content type except text, JSON and XML (and, with Fastify, compressed responses), or as decided by the
isContentTypeBinary(contentType)option. - Query strings, with Fastify, are read as sent when the event has them (payload v2, load balancers): plus signs and commas keep their meaning, as on the other adapters.
ctx.req.ipis the source IP of API Gateway, or the lastX-Forwarded-Forentry behind a load balancer (127.0.0.1with Fastify when the event has no address). Behind CloudFront or another proxy, read the right header with thegetIp(c)option ofhonoAdapter(), or thetrustProxyoption of Fastify.- Load balancers: enable the multi-value headers of the target group, to receive repeated query keys and send several cookies.
- The Lambda event and context are not given to the routes.
Configuration and secrets
Create the services of the app inside the factory, not at the top of the module: a failure is then retried at the next invocation, instead of breaking the execution environment for good.
Database connections created in the factory are reused by the next invocations of the execution environment. Size the connection pools for many small environments, or use a proxy such as RDS Proxy.
Bundle the handler
Bundle the handler and its dependencies into one file, for instance with esbuild:
Fastify and its dependencies are CommonJS modules: an ES module bundle must define require for them.
In the examples, the Hono bundle weighs about 510 kB minified (115 kB gzipped), and the Fastify bundle about 1.1 MB (300 kB gzipped).
Deploy dist/lambda.mjs with your tool (AWS SAM, CDK, Serverless Framework, Terraform…): runtime Node.js 22 or later, handler lambda.handler. See Deployment on AWS Lambda.
CORS
Configure CORS either in API Gateway or Function URLs, or in Dotpress, not both: AWS answers the preflight requests before the function runs. See CORS.
Testing
createLambdaTarget() of @dotpress/testing sends simulated API Gateway and load balancer events to your handler, without an AWS account: see Testing helpers. The Hono and Fastify examples test their handler and their bundle this way.
Event workers on Lambda
Listeners of @dotpress/events can run on Lambda too, triggered by SQS: see Event workers.