What’s the best place to host Next.js site?

You’ve built your Next.js site and now you want to put it online for the world to see. Which platform is the best to host it?

Ondrej Polesny

Published on May 19, 2021

In this article, I’ll describe Next.js specifics when it comes to deploying and hosting, introduce the four most common steps in publishing a Jamstack website, and use them to compare the four most popular hosting providers.

Next.js specifics in deployment

Next.js is a JavaScript framework for building Jamstack, or pre-generated, sites. It’s based on React, and its closest competitor is Gatsby. Next.js is very popular in the dev community, as it goes beyond static sites and allows every developer to decide whether a page should be pre-generated, server-side rendered, or composed on the client-side. But even if you aim for a fully pre-generated site, you can still benefit from server-rendered previews for editors.

If you want to leverage this benefit, it complicates the deployment a bit. There are server-side rendered pages, and for those, we need a true server, not just a static file serving CDN. 

Here are three ways to host Next.js sites:

  • True pre-generated static files on a CDN without server-side capabilities
    Examples: Azure Static Web Apps, AWS Amplify, GitHub Pages
  • Node.js hosting that uses Next.js’s production server
    Examples: Heroku, MS Azure, Digital Ocean
  • Partly pre-generated static files and partly server-side capabilities that are hosted as serverless functions
    Examples: Vercel, Netlify, Layer0

I personally prefer the last one as it allows the static files to be provided via CDN, requires less configuration, and allows each code block to be scaled separately.

It’s important to note here that not every host supports all Next.js modes. The majority of them support only true pre-generated sites and don’t offer a solution for server-side code, and thus don’t support the greatest Next.js features—incremental static regeneration, instant previews, and anything else that can’t work on the client.

I picked four providers that are capable of fully running Next.js—Vercel, Netlify, Heroku, and Layer0. To compare them, I used my own site built with Next.js that contains pages using all three page modes:

  • Client-side code that composes pages using JS bundle in the browser (Blog page and filter)
  • A pre-generated page that is composed during the site build (home page)
  • A page that requires data from server-running logic (Twitter page)

And I checked these six aspects:

  • Deploying the site from GitHub
  • Automatically rebuilding the site on code push
  • Automatically rebuilding the site on content publish
  • Verifying performance
  • Extra features
  • Pricing and free tier limitations

#1 Deploy the site from GitHub

The first use case is to set up the site and deploy the code for the first time.

Vercel

Vercel is the easiest way to deploy Next.js as it’s the people behind the platform who created Next.js in the first place. 

Vercel Import Project

The wizard asks us to select a GitHub repository and offers the standard Next.js build commands that we can override. It also lets us define all environment keys on this screen before deploying the site for the first time.

Netlify

Netlify is probably the most popular host among devs, and I believe the simple, intuitive, and fast UI plays a role in that. In the new site wizard, you can expand “advanced settings” and configure the build commands or add environment keys.

Netlify Site settings

Note that Netlify recognized that we’re creating a Next.js site and automatically installs the Essential Next.js Build Plugin, which deploys server-side code as Netlify Functions. The default settings work well.

Heroku

On Heroku, we first need to create a site. Only after that can we access the dashboard and connect the site to the GitHub repo.

Heroku Deployment method

It lets us configure automatic deployments, but the UI is not 100% clear. To configure the environment variables, we need to navigate to the Settings tab and Config Vars section.

Heroku Config Vars

By default, Heroku will build the app and run the next start command to start the Next.js production server. It does not convert anything to serverless functions—Heroku is a Node.js hosting service. The problem is that Heroku uses a random port, and Next.js is configured to use 3000. So we need to adjust the port on which Next.js server runs by adding a special file called Procfile (the filename is case-sensitive):

web: next start -p $PORT

Layer0

All the previously mentioned hosting providers also feature build tools, which means that they take the code from a GitHub repo, build it, deploy it, and host it. Layer0 does not offer a way to build your code after receiving a webhook notification from GitHub, so you either need to build & deploy manually or leverage a CI tool like GitHub Actions.

npm i -g @layer0/cli

layer0 deploy

The deployment is done in these two steps, and Layer0 will automatically create an app for you. Then you can adjust its settings and add environmental variables.

Layer0 New Environment

Note: Layer0 installs a bunch of packages (as dev dependencies) into your site that are related to some extra features mentioned later in this article

Results:

VercelNetlifyHerokuLayer0
10/1010/10

6/10

The UI is not ideal, and I needed to check logs and google the Procfile solution after getting a 503 error.

6/10

You need to configure a CI process to get the site up and running. The UI, despite being very detailed, is nice and intuitive.

#2 Automatic build on push

We make a code change, commit, push to the GitHub repo. GitHub creates a webhook notification to the build server, which builds the site and deploys it to production.

Results:

VercelNetlifyHerokuLayer0
10/1010/1010/10

0/10

We need a GitHub Action or another CI tool for this task. However, Layer0 offers a template in their docs.

#3 Automatic build on content publish

Content changes trigger a webhook notification to the build server, so the scenario is very similar to automatic build on push. We need a URL, a target of our content change webhook notifications.

Vercel

We can create a deploy hook under Settings and Git.

Vercel webhooks

Netlify

Find the “Build hooks” section under Site settings, Build&Deploy, and Continuous Deployment.

Netlify webhooks

Heroku

Generating a unique URL for these notifications is not supported. You can work around this limitation by mocking a GitHub push notification via a special API as described by Matteus Deloge:

POST https://kolkrabbi.heroku.com/apps/<HEROKU_APP_ID>/github/push

Body: {
    "branch": "master"
}

You will also need to fetch the application ID either by CLI:

heroku apps:info --json

Or by another API call:

GET https://api.heroku.com/apps/<HEROKU_APP_NAME>

Headers: {
    "Accept": "application/vnd.heroku+json; version=3"
}

Both requests need to have an Authorization header with an API Key you can find under Account settings:

Headers: {
    "Authorization": "Bearer <API_KEY>"
}
Heroku Webhooks

The other option is to move your build process to another tool like GitHub Actions with better capabilities for triggering builds.

Layer0

The platform does not offer to host the build process. You need to move it to a tool like GitHub Actions and handle the webhook notifications there.

Results:

VercelNetlifyHerokuLayer0
10/1010/10

4/10

Triggering builds via external webhook is not natively supported.

0/10

Layer0 does not offer build server capabilities but offers a template for GitHub Actions in their docs.

Note: You can also keep your site up to date using incremental static regeneration as described here. That way, you won’t need to configure and use webhooks anymore.

#4 Verify performance

In this category, I evaluated both the build process and the front-end performance. I used web.dev test on all four deployed sites, and apart from learning that I should make some adjustments in the implementation, for each host, I recorded two metrics that are related to the actual hosting server:

  • First contentful paint
    That is, how long it takes to see the first content appear on the blank browser canvas.
  • Largest contentful paint
    The render time of the largest image or text block visible within the viewport.

I conducted three tests focused on each metric (except the first build time) and calculated their average values.


VercelNetlifyHerokuLayer0
First build+deploy time49.3s1m 57s1m 20s3m 37s*
Subsequent build+deploy time42.6s1m 37s1m 15s1m 51s*
Pre-generated page FCP2.4s2.3s3.0s2.7s
Pre-generated page LCP4.4s 4.3s6.0s4.1s
SSR page FCP2.4s2.3s2.6s2.3s
SSR page LCP4.4s4.6s5.9s4.5s
Result10/108/107/108/10

* Layer0 deployment process builds the site on your local machine and only then deploys it, so these figures were affected by my computer’s power and network connection. They can be different for deployments from CI tools.

Note: Pre-generated page and SSR page have different content, so only results in the same row are comparable.

* Update 2021-06-07: The pre-generated page used for testing contained assets linked to our CDN. I repeated the speed tests on the website homepage and updated the table.

#5 Extra features

Each of these platforms provides some additional features to help us deal with optimizing the site or advanced scenarios. In this section, I only outline the features that stand out for developers.

Vercel

The site is running Next v10, so we can fully leverage Vercel’s Analytics. Instead of measuring web vitals using a tool such as web.dev, Vercel gives us insight into the actual visitor’s experience. It collects data from the deployed site and builds a summary that we can filter by device and time. Analytics are available for every page of the site, so it’s possible to quickly identify a bad performing page.

Vercel Analytics

Result: 8/10

Netlify

Netlify also provides Analytics, but not by collecting data from visitors. They collect data server-side. To enable the feature, you need to upgrade to a paid plan.

Netlify offers multiple extra features that are designed to simplify Jamstack (and beyond) sites such as Identity management, A/B testing, and so on. While you may not need these enhancements on all your sites, you almost always need to manage form submissions. The Forms management on Netlify allows a quick integration:

<form name="contact" method="POST" data-netlify="true">

And it also collects all submissions in the same UI of Netlify administration.

Netlify Forms

It supports email/webhook/Slack notifications, reCaptcha, and file uploads.

Result: 10/10

Heroku

The deployed site on Heroku runs as a Node.js app, so the platform offers tools for monitoring the server metrics such as memory usage, throughput, response time, and so on. You can also configure autoscaling to handle traffic peaks.

When hosting the Next.js site on Heroku, you’re one level higher in terms of abstraction. Heroku doesn’t support Next.js directly—it gives you the tools (Node.js server) to host it. Heroku offers a gallery of server-level add-ons for many use cases and platforms, but none of them are specific to Next.js or Jamstack. However, for some projects, this freedom may be a benefit.

Result: 3/10

Layer0

In the deployment section, I complained that Layer0 adds some dev NPM packages to the site. Here I learned why. The deployed site displays dev tools that show network stats for every visited page. You see how long it took to load every asset the page needs, where the file was served from. In addition to that, no requests happen once the bundle is loaded and moving between pages is handled locally. Very cool.

Layer0 Devtools

Apart from that, Layer0 can track the core web vitals of your site as long as you put a tracking script in the header of all pages. It also supports multiple site environments, which simplifies the setup if you need a preview version of your site.

Result: 10/10 

#6 Check pricing and free tier limitations

All platforms provide a free plan. This table shows the features provided by each host in its scope and tells you when you’re going to need to start paying.


VercelNetlifyHerokuLayer0
Custom domainyesyesyes, but only without SSLyes
Commercial projectsnoyesnono
Deployments100/dayunlimitedunlimitedunlimited
Serverless functions12/deployment125k executions/monthnot applicable100 hours/month
Serverless function timeout10s10s30s timeout for any request20s
Team members1153
Build time

45m/deployment

100h/month

300 min/monthunlimitednot applicable
Analyticsyesnonoyes
Bandwidth100GB/month100GB/month2TB/month100GB/month
Always onyesyessleeps after 30minyes

The free plans are comparable, and it depends on your project which limit might become a bottleneck.

Conclusion


VercelNetlifyHerokuLayer0
Final result48/5048/5030/5024/50

So, which one is the best? As usual, there’s no silver bullet, and the choice depends on the project and the developer. The test cases were focused on the simplicity of deployment and basic tasks a developer needs to do to get a Next.js site live. If a host received fewer points in this test, it doesn’t mean they’re a bad service and may excel in another aspect that was not measured. The different possibilities of each platform and the requirements of a specific project may shuffle the results and point you in another direction.

I am a fan of hosting the site on CDN with the help of serverless functions. It requires very little maintenance and is easily and granularly scalable. I also like it when the hosting platform takes care of the build automatically without configuration and is capable of triggering it in case of code and content changes. That helps me stay in the code rather than become a DevOps expert 😊.

Tell me where you host your sites and why on our Discord 😎.

Subscribe to the Kontent.ai newsletter

Get the hottest updates while they’re fresh! For more industry insights, follow our LinkedIn profile.