Grass logo

Cache Static Assets with NextJS using CDN and Cache Headers

15th Nov 2022

After adding tracing data to our Layer3 servers, a new world has opened in terms of performance optimization.

Looking at the most frequent request hitting our servers, I noticed that static assets like /images/fav/favicon-196.png were among the top.

Considering our website is behind Cloudflare, I really thought these kinds of assets were cached.

During our traffic surges, with performance bottlenecks and our services struggling to be responsive, our server has been handling thousands of static asset servings.

Such a waste of precious CPU power.

Figuring out why our assets were not cached

When inspecting headers, it turns out NextJS adds a Cache-Control: public; max-age=0 header.

This means Cloudflare, or any CDN won’t cache this at all.

It can be fixed by adding this to next.config.js:

async headers() {
  return [
    {
      // list more extensions here if needed; these are all the resources in the `public` folder including the subfolders
      source:
        "/:all*(svg|jpg|png|ico|webp|manifest.json|json|txt|js|css|woff|woff2|ttf)",
      headers: [
        {
          key: "Cache-Control",
          value: "public, max-age=3600",
        },
      ],
    },
  ]
},

With this config, static assets will be cached for 1 hours (3600 seconds).

Our response headers now look like this:

Hi!

I'm Lars. I write about building scalable systems, software architecture, and programming.

I created Turfemon to be my playground. A place where I can dive into technical topics, share quick insights, and document my learning journey, without contaminating my main site's pristine collection of 'profound' insights.

Working on something exciting? Send me an email: show email