Next.Js Deployment/Hosting Findings

Introduction

The TSS frontend app was originally built using create-react-app (CRA), which, although popular, is now deprecated and lacks support for server-side rendering. To enhance flexibility, the app was wrapped in Next.js; however, TSS has not yet fully taken advantage of the latest features available in React and Next.js. Therefore, it’s essential we investigated the optimal deployment or hosting setup to ensure we can effectively utilize these advancements moving forward.

Sample App link

 Deployment Hosting Platforms Investigated

  • AWS Lambda

  • AWS Amplify Hosting

  • AWS Elastic Container Service

  • Vercel

Acceptance Criteria

The investigation used the following acceptance criteria:

  • Cost

  • Complexity

  • Ease of deployment

  • Performance

  • Resilience

  • Scalability

  • Securely accessing private resource (e.g. internal API endpoints)

 Architecture

 

 

 Findings

AWS Lambda (ticket)

Using AWS Lambda allows developers to run code without the need for server management, paying only for compute time used. This serverless model means there are no costs incurred when the code isn’t running, which can lead to "cold starts" when new requests trigger a dormant function.

However, deploying Next.js on AWS Lambda presents challenges due to its file generation process, which can create outputs exceeding Lambda's 250MB size limit. This necessitates the use of specialized frameworks to facilitate deployment.

While frameworks like SST and AWS SAM can be useful, they often require adjustments to handle Next.js’s file size constraints. To address these limitations, I found that using a combination of SAM and Docker approach with the AWS Lambda Web Adapter is beneficial.

The AWS Web adapter enables the deployment of existing Next.js applications as Lambda functions without major code changes. It also acts as a proxy, reducing cold start times, although the first execution can still result in longer cold starts.

AWS Elastic Container Service ECS (Ticket)

I explored deploying the NextJS application on AWS Elastic Container Service (ECS), a managed service for orchestrating containerized applications. Deployment involves containerizing the application, pushing it to Amazon ECR, and defining a task definition template alongside service configurations and IAM roles.

Using Terraform, I deployed the sample application with Fargate, allocating 256 CPU units and 512 MB memory, and configured autoscaling with a desired task count of 3.

To test for performance I used K6 to load test the deployed code:

  • Single Task: 100% success for one endpoint, 99% for the API. Response times exceeded 500ms for four requests, with CPU utilization over 60%.

  • Three Tasks: All requests responded in under 500ms with no failures, demonstrating high availability and fault tolerance with effective autoscaling.

The results indicate that AWS ECS can maintain performance and resilience, particularly under higher load scenarios.

AWS Amplify Hosting (Ticket)

The Next.js Sample application was also deployed using AWS Amplify Hosting, a fully managed CI/CD and hosting service suitable for static and server-side rendered apps.

Deployment Steps:

  1. Connect Repository: I connected the repository containing the Next.js code to AWS Amplify and authenticated the connection.

  2. Configure Application: I specified an application name and selected the branch to deploy from. Amplify supports both monorepo and multibranch builds, which provided flexibility for managing different environments.

  3. Automatic Setup: Amplify automatically detected that I was using Next.js, configuring the necessary build settings and running yarn install to install dependencies.

  4. CI/CD Integration: I set up hooks with the repository, enabling Amplify to trigger a new build for every merge request, streamlining the CI/CD process.

  5. Hosting Features: Amplify has hosting features, including custom domains and redirects, which can be configured too using the Amplify UI or CLI tools for a seamless integration.

  6. Testing: AWS Amplify also offer testing capabilities to run Cypress tests, this can help ensure application quality during deployment process.

Overall, deploying Next.js on AWS Amplify was efficient and user-friendly, leveraging its managed services and automated features to ensure a reliable deployment. The artifact size limit of 5GB which was adequate for this implementation.

Vercel Hosting (Ticket)

Vercel is a developer-focused platform that simplifies building and deploying web apps, especially for Next.js, which it created. Deployment is straightforward: connect the code repository, click deploy, and Vercel handles the rest, including generating deployment template.

Key Features:

  • Native support for SSR, caching, and monitoring.

  • Speed insights can be enabled with npm install @vercel/speed-insights.

  • Analytics support includes 2,500 events/month on the hobby plan and 25,000 on the pro plan.

Deployment steps

  1. Created a Vercel account and added a new project.

  2. Connected my Next.js repository and deployed.

  3. Received an auto-generated *.vercel.app domain, which can be customized.

Billing: Plans include Hobby (free), Pro ($20/month per collaborator), and Enterprise (with additional benefits).

Billing: Vercel offers three plans—Hobby (free), Pro ($20/month per collaborator), and Enterprise (with enhanced benefits).


 

LAMBDA

ECS

AMPLIFY

VERCEL

 

LAMBDA

ECS

AMPLIFY

VERCEL

1

COST

  • ECS Cost depends on the number of task running, the vCPU and Memory allocated to the task, and other associated costs like Load balancer, storage, etc.

  • For our case study, using Fargate, 256vCPU and 512GB Memory and 20GB storage, with one Task will cost about $10.20 a month, and about >=$31 if we auto scale to 3

  • Sample cost estimate

  • Relatively Cheap and cost effective.

  • Amplify offers a free tier for the first 1000 build minutes and the cost is $0.01 after.

  • For Hosting, cost is based on storage, data transfer and requests.

  • Sample cost estimate

The cost for the pro plan is $20 per collaborator.

Additional costs include compute expenses, edge request fees, storage, data transfer, monitoring, and other related charges.

2

COMPLEXITY

  • Because of lack of control of underlining resources, management could get complex with relatively high volume of requests.

  • Also cost could skyrocket if there is any endpoint making synchronous invocation concurrently in loop. or DDOS.

  • low to Moderate complexity. To setup there are various components to account for such as Task definition, service, autoscaling, networking, etc.

  • The platform abstracts much of the underlying complexity.

  • With automatic build and deploy process manual configuration is highly reduced.

  • Low Complexity

Relatively easy for UI based operations. All Vercel operations can be done Using the UI.

There is also a terraform Provider for Vercel for IAC configuration

3

EASE OF DEPLOYMENT

When the framework for Deployment of the Next.Js project is decided, deployment can be relatively easy (SAM + Docker in our case).

Also CICD can simplify deployment further further.

Deployment is simple and easy with IAC and CICD.

Require experience and Expertise with the required tools.

Deployment is very easy and simple with Amplify.

  • You connect the repository and Amplify handles the build and deploy process

Vercel deployment is easy and straightforward.

4

PERFORMANCE/SCALABILITY

Performance: Good Performance, though there is cold start, it was almost unnoticeable.
also there is the 15 minute timeout which is not suitable for long running tasks.

Scalability:
Relies on Serverless advantage of high scalability and Lambda scale to Zero.

  • Highly scalable.

ECS is highly scalable, as it integrates with Autoscaling to dynamically adjust container count based on traffic.

Highly performant as Fargates helps to achieve this autoscaling without managing servers.

Amplify has high performance as it can handle sudden traffic spike and scale horizontally, its underlying resources are serverless.

For load test; same scenario as the lambda’s all request was successful.

  • Highly scalable.

Vercel is a serverless Platform and hence boast of great scalability and performance.

There are other features that can be integrated to applications from Vercel UI, such as WAF, Caching, DB, etc.

5

RESILIENCE

Highly resilient with built in redundancy, high availability and good error handling.

Lambda also has native integration with CloudWatch.

ECS ensures high availability and integrates with Load Balancers (ALB or NLB) to distribute loads across auto scaled tasks.

Fargate is highly resilient with AWS managing the infrastructure, it abstract fault tolerance.

Highly resilient, with its underlying AWS Infra, it benefits from AWS’s Global network, redundancy and failover mechanisms.

It also has native integration with CloudWatch.

Vercel's Edge Network is designed with high availability and fault tolerance in mind

Also Vercels resources are backed by AWS cloud platform, hence are resilient. they can scale with user base. It also has monitoring and analytic capability to measure performance and detect issues in time.

6

INTERNAL API ACCESS

Lambda in VPC mode can access Private internal endpoints and resources securely.

With ECS we can easily access internal API.

ECS offers service discovery and Networking capabilities(including VPC, subnets and security groups) to handle internal API communication.

Amplify do not have VPC integration and hence not suitable for accessing internal API like private backend URL or database.

 

Vercel do not have a way or function to integrate with internal APIs running on different environments for Pro or hobby plans.

 

Recommendations

This recommendation is based on services that meets the Acceptance Criteria

  1. AWS Elastic Container service:

    • In my investigation of AWS ECS, I observed that while loading the web page in a browser is fast and the cold start issue is not noticeable during typical usage, it does become apparent during K6 load testing with a small number of users and a simple app with two routes. For user-facing applications, I generally prefer platforms that minimize or eliminate cold starts.

    • ECS is particularly well-suited for predictable use cases, such as trainee frontend applications. Given that my final output is a Docker container, I recommend using ECS for hosting the Next.js frontend. Leveraging the serverless capabilities of Fargate, ECS serves as a robust container orchestration platform that effectively manages container-based applications.

    • One of the key advantages of ECS is its greater control over resource allocation compared to AWS Lambda, allowing us to optimize costs for long-running tasks and high-throughput applications. However, it’s important to note that ECS can be more expensive than Lambda, although Lambda's costs can escalate rapidly under high usage scenarios.

  2. AWS LAMBDA

    • AWS Lambda operates on a pay-per-use basis, charging only for compute time, which is ideal for serverless Next.js applications with variable traffic and no upfront costs for idle capacity. Lambda can scale to Zero when the function is not serving request hence saving cost. from a cost perspective Lambda is a cheaper option compared to ECS as shown in the Pricing calculator cost comparison.

    • Lambda automatically scale to handle varying traffic loads, efficiently managing sudden spikes without the need for pre-provisioning resources.

    • With AWS SAM, Docker and AWS Lambda web adaptor, deployment and future code update can be seamless and easy.

Trade-offs in Choosing AWS Lambda vs. ECS

  • AWS Lambda: The trade-off is reduced control over underlying resources and less predictability in costs, especially during peak usage.

  • AWS ECS: The primary trade-off is higher costs, as it can be more expensive compared to Lambda, because of the resources it hooks with at the background. E.g. Load Balancer

 

 References and documentation