Skip to content
CirruSoul

A 97-score Next.js site on a 1 GB server

You don't need a big cloud bill for a fast website. How we self-hosted a brand site with Nginx, HTTP/2 and an image cache.

CCirruSoul Technologies Team22 Oct 20263 min read
DevOps

A 97-score Next.js site on a 1 GB server

For the Luxe Luffa brand site we wanted top Lighthouse scores without paying for a managed hosting platform. Everything runs on one small AWS instance with 1 GB of RAM. This is how we set it up, and what actually moved the numbers.

Why self-host at all?

Managed platforms are excellent, and for many teams they are the right call. But a brand or company website with moderate traffic doesn't need them. A single small server gives you a fixed, predictable monthly bill, full control over caching, and one less vendor to manage. The trade-off is that you own the setup — so the setup has to be simple and scripted.

Build on the server, safely

A 1 GB machine can run out of memory during next build. Two changes fixed it:

  • Add swap. A 2 GB swap file gives the build room to finish instead of being killed.
  • Cap Node's heap. Setting --max-old-space-size keeps Node from trying to use more memory than the machine has.

A single deploy script uploads the code, installs dependencies, builds, restarts the app under pm2 and then requests the home page to confirm the site responds. If the check fails, the previous build keeps running.

Let Nginx do the heavy lifting

Next.js runs behind Nginx, which handles everything a reverse proxy is good at:

  • TLS with a free Let's Encrypt certificate that renews automatically;
  • HTTP/2, so the browser loads many files over one connection;
  • compression for HTML, CSS and JavaScript;
  • image caching — each resized image is generated once by Next.js and then served from Nginx's cache;
  • a one-year cache header for hashed build assets in /_next/static, which never change once deployed.

Fix what the user actually waits for

The first Lighthouse run scored 70 on mobile. The biggest problem was the hero photo: a 2000-pixel image downloaded straight from a stock-photo CDN, on every visit, on every phone.

Routing all images through the Next.js image optimiser — resized, WebP, served from our own domain — took the Largest Contentful Paint from 6.9 s to 2.3 s on mobile. We also:

  • marked the hero image as a priority image, so it starts loading immediately;
  • gave every image explicit dimensions, so the layout doesn't jump;
  • inlined the small Tailwind stylesheet, removing one more round trip before the first paint.

Final scores: Performance 95–97, and 100 for accessibility, best practices and SEO.

SEO basics that cost nothing

Speed helps, but search engines also need to understand the site. On the same deploy we added:

  • a unique title and description on every page;
  • a canonical link on every page;
  • an XML sitemap and a robots.txt file;
  • structured data (schema.org) for the organisation and its products;
  • social preview images, so links look right on WhatsApp and LinkedIn.

The part code can't fix

The server sits in a US region and most visitors are in India — roughly 300 ms for every round trip. No amount of code changes that. The next step is a CDN in front of the server, or moving it to the Mumbai region. That is an infrastructure decision, and an easy one once the rest is in place.

Checklist

  • Swap and a heap cap for builds on small servers.
  • One scripted deploy with a health check.
  • Nginx for TLS, HTTP/2, compression and caching.
  • Every image through the optimiser, with sizes and a priority hero.
  • Titles, canonicals, sitemap and structured data on day one.
  • Host close to your users.

Want a faster site without a bigger bill? Get in touch.

  • #Next.js
  • #Nginx
  • #Performance
  • #AWS