[KongchangAI]
· 3 min read· 1,629 words

AWS Lambda Web Functions Tested: Can It Replace Amplify for Next.js Deployments?

AWS Lambda Web Functions Tested: Can It Replace Amplify for Next.js Deployments?

Hands-on comparison of Lambda Web Functions vs Amplify hosting a Next.js app, with strong gains in dynamic rendering and streaming.

A developer compared the same Next.js 15 app on AWS Amplify and the newly released Lambda Web Functions. Web Functions run an HTTP server directly, support up to 128 concurrent requests per environment, and offer native streaming; Amplify relies on built-in CloudFront but lacks Next.js streaming and on-demand ISR. Results: Amplify is faster for static pages (43ms vs 288ms), while Web Functions dominates dynamic SSR pages (checkout to summary 244ms vs 1582ms; order page refresh 121ms vs 1410ms). The author leans toward migrating, though small teams may still prefer Amplify's managed convenience.

AWS recently launched Lambda Web Functions, aiming to provide a more direct and efficient hosting approach for web applications. A developer who has long struggled with Amplify ran a comparative test using the same Next.js application on both platforms, and the results are quite instructive.

AWS Lambda Web Functions console experience

Why Web Functions Are Worth Paying Attention To

Traditional Lambda (now called Lambda Event Functions by AWS) receives events and returns responses, while a standard Next.js production server listens on an HTTP port and continuously serves requests—the two models don't match. Lambda Web Functions directly run an HTTP server; the application listens on a host and port provided by Lambda, and AWS handles the HTTPS endpoint, execution environment, and scaling. There's no API Gateway pretending to be HTTP requests, and no framework-specific adapters needed.

The more critical change is in the concurrency model. A warmed-up Web Function can serve multiple requests simultaneously, unlike traditional Event Functions which handle one request at a time with single concurrency. AWS documentation shows up to 128 concurrent requests per environment, with actual concurrency dynamically managed. This is valuable for web applications that need to wait on databases or other AWS services. The billing model has been adjusted accordingly: Web Functions are billed by active CPU time, CPU consumption is low during I/O waits, and memory is still billed by environment lifecycle.

Additionally, Web Functions support native response streaming, offer Node.js 24 on Arm64 at launch, and come with immutable revisions, traffic routing endpoints, and optional multi-region routing.

Lambda's concurrency model has undergone significant evolution. Traditional Lambda processes only one request at a time per instance; if concurrency is high, AWS needs to spin up many instances, leading to frequent cold starts and low resource utilization. Web Functions introduce a "multi-concurrency per environment" mechanism—a single execution environment can handle up to 128 requests simultaneously, dynamically scheduled within the environment by AWS. This is similar to Node.js's event loop: when one request is waiting on I/O (such as a database query), the CPU can switch to handling other requests. This model is closer to the behavior of a typical web server and can significantly reduce wait times, but requires application code to be concurrency-safe and avoid relying on global mutable state.

Test Design: One App, Two Deployments

The author built a fictional food delivery app called Fin & Feast using AI, with Next.js 15, TypeScript, and the App Router. The homepage renders dynamically and reads request information, dish pages are statically generated, the checkout flow validates the cart and calculates prices server-side via /api/orders, and the order confirmation page uses signed HttpOnly cookies for personalization. The homepage availability panel and order progress panel are placed behind React Suspense boundaries with an intentional ~1 second delay to distinguish between "streaming out page fragments" and "waiting for everything to be ready before outputting."

Both deployments are managed with Terraform. The Amplify approach connects to a GitHub repository, with AWS building and hosting it, including a CloudFront distribution. The Web Functions approach requires handling everything yourself: building Next.js in standalone mode in a Linux Arm64 build container, packaging into a ZIP and uploading to S3, having Terraform create a Web Function revision pointing to a specific object version, and pointing the HTTPS endpoint to that revision.

The test uses Playwright to drive the same flow: loading the dynamic homepage and waiting for availability, opening the static dish page, navigating via Next.js prefetch, adding to cart, checking out, and refreshing the personalized order page. The main run includes 1600 measured journeys and 800 warm-up journeys, alternating platform order to reduce bias.

Test Results: Static Delivery vs Dynamic Rendering

MetricAmplify MedianWeb Functions MedianAmplify p95Web Functions p95
Homepage TTFB1803 ms297 ms1893 ms369 ms
Static dish page TTFB43 ms288 ms108 ms355 ms
Prefetch navigation to dish page44 ms44 ms60 ms60 ms
Checkout to order summary visible1582 ms244 ms1684 ms296 ms
Direct refresh of order page to summary visible1410 ms121 ms1524 ms171 ms
Order refresh summary to progress interval24 ms1192 ms25 ms1288 ms

For the static dish page, Amplify is only 43 ms, far faster than Web Functions' 288 ms. The author believes this is mainly thanks to Amplify's built-in CloudFront CDN. In repeated browser tests, this static page is about 16 ms on Amplify and about 96 ms on Web Functions. This proves that CDN really does help—probably not surprising.

What really creates the gap is pages requiring server-side computation. After checkout, Web Functions repeatedly shows the order summary and progress page faster than Amplify. When directly refreshing the order page, Web Functions shows the summary faster, but the interval from summary to progress component reaches 1192 ms, while Amplify is only 24 ms—the latter means both blocks arrive together, but users wait much longer for the first useful byte. This is consistent with Web Functions' streaming response behavior and also matches AWS documentation stating that Amplify doesn't support Next.js streaming.

The author's colleague believes the main difference may come from Web Functions' parallel request model, similar to what Vercel implemented to reduce hosting costs and improve response speed: one Lambda instance connects to the routing layer and handles multiple requests. He suspects Amplify still uses one Lambda instance per request, leading to frequent cold starts. Prefetch navigation is 44 ms on both sides, indicating this path is determined by the browser rather than the hosting environment.

Streaming responses are a core feature of React 18 and Next.js App Router. It allows the server to first send the page shell and ready static parts, then progressively send dynamic content behind Suspense boundaries via HTTP chunked transfer. The browser can render as it receives, and users can see partial content without waiting for all data to be ready, improving perceived performance. In the test, the interval from summary to progress component on the Web Functions order page is as long as 1192 ms, precisely because the summary is streamed first while progress data is still loading asynchronously. Amplify doesn't support streaming, so it waits for all component data to be ready before sending at once, resulting in a later first useful byte, but components appear to arrive simultaneously.

Trade-offs Between Streaming and CDN

Amplify's advantages are concentrated in static delivery and its built-in CDN, while Web Functions' advantages are concentrated in dynamic server-side rendering and streaming. The author admits that Web Functions doesn't come with a CloudFront distribution, and he didn't deploy one this time—in hindsight, he thinks he probably should have. AWS supports using Web Functions as a CloudFront origin, including origin access control, so adding a CDN is a matter of minutes.

Another noteworthy detail is that Amplify's environment variables aren't automatically visible to Next.js server components; they must be explicitly written at build time. This is an extra cognitive burden specific to Amplify. Additionally, Amplify's Next.js support documentation lists support up to Next.js 15, but explicitly excludes streaming and on-demand ISR.

On-demand ISR (Incremental Static Regeneration) allows Next.js to regenerate static pages on demand at runtime: when a request arrives, if the cache has expired, the server regenerates the page in the background and updates the cache while immediately returning the old version. This differs from traditional build-time static generation and is better suited for scenarios where content updates frequently but traffic is high. Amplify documentation explicitly states it doesn't support this feature, mainly because its hosting model can't trigger Next.js's revalidation logic when receiving requests. If your application relies on on-demand ISR, migrating to Lambda Web Functions or another platform that supports full Next.js server functionality would be a more reliable choice.

Can We Say Goodbye to Amplify?

The author's attitude leans more toward migration than before the experiment. Web Functions directly run the Next.js standalone server without trying to reinterpret the framework with another hosting model. Build and deployment are simpler, Terraform descriptions are clear, and revisions point to specific versioned artifacts. Adding CloudFront is just a few minutes of work.

The cost is that CDN, build hosting, and environment integration that Amplify used to handle for you become your own responsibility. For teams pursuing predictability and streaming capabilities, this trade-off may be worth it; for small teams that just want to click a few times and get running, Amplify's managed wrapper still has value. The application code, Terraform, and Playwright benchmark scripts are all open-sourced, so you can reproduce them yourself.

One-line Summary

A hands-on comparison of Lambda Web Functions vs Amplify for hosting a Next.js app, with significant advantages in dynamic rendering and streaming.

Paragraph Summary

A developer performed a detailed performance comparison of the same Next.js 15 app on AWS Amplify and the newly released Lambda Web Functions. Web Functions directly run an HTTP server, support multi-request concurrency (up to 128 per environment), and native streaming responses; Amplify relies on its built-in CloudFront CDN but doesn't support Next.js streaming or on-demand ISR. Test results show Amplify is faster for static pages (43ms vs 288ms), but Web Functions significantly outperforms on dynamic server-rendered pages: checkout to order summary 244ms vs 1582ms, direct order page refresh 121ms vs 1410ms. The author believes Web Functions returns CDN, build hosting, and other responsibilities to developers in exchange for a more predictable deployment model and stronger dynamic rendering capabilities, and leans toward migrating—though small teams may still prefer Amplify's managed convenience.

#AWS Lambda Web Functions#AWS Amplify#Next.js deployment#streaming SSR#serverless hosting
Share:

Related articles