How to fix cold start problem for Next.js SSR Websites hosted on AWS Amplify

Resolving Cold Start Issues for Next.js SSR Websites on AWS Amplify: Strategies to address and mitigate the cold start problem, optimizing performance for server-side rendering on the AWS Amplify platform.

We were really excited when we rolled out our website. Foreseeing the SEO needs, we planned to make it on Next.js, which is great for SEO since it provides SSR capabilities. We also decided to host it out of AWS Amplify because of it initial free tier. Other option was to host it on Vercel, which has is paid after a free trial. As soon as we hosted the website on Amplify, we noticed a cold start for the website which took around 6-8 seconds to Time to First Byte (TTFB). After a quick search, we found that this is a know issue with amplify.js.

This blog will address on how to get rid of the cold-start without spending a fortune or moving to Vercel.

There are quite a few solutions to this problem, I will list a couple of them down here and also tell you what we implemented to get the most out of Amplify.

Setting up a Health Check in Route 53

Simplest way would be to setup a Route 53 Health Check to your web page. How Route 53 Health Checks work is, they ping the HTTP/HTTPs resource and if the resource doesn't respond within 4 seconds, it fails. Now, rumoured (because who know what is a lambda upto) life of a warm lambda is around 7 minutes, pinging it every 30 seconds (which Route 53 Health Check does, will keep it warm.

Go to Route 53 and select Health Checks
Go to the Health Check

Now, you will want to populate all the required field.

You can populate the required field

You can enter your Domain Name which would be the amplify link from your amplify console, which looks something like main.d3gi2qh3ng78gl.amplifyapp.com, and any necessary path that you have on website to monitor health check.

Most of us would initially put their website to be pinged by this health check. Good thing about this is it provides Health Checker Regions, which keeps the Lambdas alive across a lot of customizable AWS Regions, minimum 3 regions will have to be configured.

Problem with this Approach

We setup up our home page as the health check path, the problem with it was that the website itself was around 300KBs (scripts and css without other resources) and we ran out of Free tier of data transfer (15GBs) because the data consumed was 300KBs * 6 (requests per minute) * 1440 (minutes per day) = 2.5GBs

Final Solution

We were amassing a lot of AWS Bill, when we came across a fantastic solution, which involved creating a dummy endpoint on the seemingly only Static Next.js app to return a healthy response.

You can do this if you are using page router of Next.js -

export default function handler(req: any, res: any) {
  res.status(200).json({ "status": "ok" })
}

Or, if you are using Next.js 13 and app based router, you can do -

export async function GET(request: Request) {
	return new Response(JSON.stringify({"status": "ok"}), {status: 200})
}

This, will effectively bring down your Total bytes downloaded by the Health Check pingers to mere few KBs.

Hence, you can keep your Next.js warm just for $1, which is the Route 53 Health Check charge.

Refs -

https://github.com/aws-amplify/amplify-hosting/issues/3211#issuecomment-1630968464

https://gushwork.ai/