Adam Jones|HomeBlog

Follow-up: benchmarking Next.js server vs nginx at serving a static site, now on AWS

Headshot of Adam Jones

Adam Jones

Yesterday, I published a benchmark that compared a few different ways of hosting a static Next.js site. I tested against a server running locally to focus as much as possible on the performance difference between the tools alone.

However, in the real world your servers are far away!

I wondered how this would affect the test results. My main assumption would be that it just adds some constant to all of them. But why not test, given I’ve got almost everything so easily set up for that now?

I spun up the same setup on a t2.micro instance running Ubuntu 24.04 on AWS EC21, and re-ran the tests.

The first time I did this, I got very weird results. I realised this was because Next.js was just dropping a lot of the requests. I decreased the rate from 5000 to 100 to help it better cope with this.

Here are the results after making this change:

Median HTTP load times, high reqs/second (i.e. for the HTML response, using k6):

Median page load times, no additional reqs/second (i.e. for the browser to consider the page fully loaded, using Puppeteer):

Full results
nginxnext startnext dev
load_passes500500500
load_avg126.0101826106.574511388.8905562
load_med107.971812102.241167357.8632295
load_p90212.3881503116.0010872488.5655202
load_p95227.4584729127.3348625556.4741458
req_passes590357015669
req_duration_avg17.3915603319.06719033293.9646488
req_duration_median17.158518.2442.709
req_duration_p9019.01121.55321169.528
req_duration_p9520.455227.509751392.9619

Benchmark source code.

Takeaways

At low load, moving to a remote server increases latency across the board. Surprisingly, Next.js actually starts to do slightly better than nginx: I’m not certain why this is the case. It could be various optimisations like their image optimisation (although I’m not certain this was enabled).

At higher load and measuring HTTP request times, nginx just takes the lead by a couple of milliseconds: but the difference is pretty small (note this is at much lower volumes than yesterday’s post).

This experiment also reinforced my belief that nginx is more of a pain to setup. Next.js ‘just worked’. I cloned the repo, did an npm install and things were happy. nginx required fiddling with the config file (I ended up using the absolute path rather than relative path with PWD to get it working), all the while being annoying to troubleshoot.

I think yesterday’s takeaway still holds: that in practice the performance penalty for picking Next.js over nginx is often worth the setup hassle.

Footnotes

  1. Hosted in eu-west-1, while I was sending requests from a high-bandwidth business internet connection in London.