How to configure caching headers on Netlify

How to configure caching headers on Netlify

Perttu Lähteenlahti
3 min read
headerscachingperformancecdn
Share:

Introduction

Caching is one of the biggest performance wins you can get on the web, but it’s also one of the easiest things to get wrong. Cache too aggressively and users see stale content. Cache too little and you lose most of the benefit of a CDN.

Netlify gives you fine-grained control over HTTP headers so you can tune caching behavior exactly the way your site needs. In this guide, you’ll learn how Netlify headers work, how to configure them, and how to apply sensible caching strategies for common use cases.

How Netlify handles caching

Netlify sits in front of your site as a global CDN. By default:

  • Static assets like images, JS, and CSS are cached aggressively
  • HTML is cached conservatively to avoid serving stale pages
  • The CDN respects standard HTTP cache headers

You can override and customize this behavior by defining headers explicitly.

Ways to define headers on Netlify

There are two supported ways to configure headers:

  • Using a _headers file
  • Using netlify.toml

Both approaches are equivalent in terms of capabilities. Choose the one that fits your workflow.

Using the _headers file

The _headers file lives at the root of your published site (usually the build output directory).

Example structure:

/public
  |_ index.html
  |_ _headers

Basic syntax:

/path
  Header-Name: value
  Another-Header: value

Example: cache static assets aggressively

/assets/*
  Cache-Control: public, max-age=31536000, immutable

This tells browsers and Netlify’s CDN to cache files for one year and never revalidate them.

This works best when filenames include a hash (for example, app.83hd73.js).

Using netlify.toml

If you prefer configuration in code, netlify.toml is usually the better option.

Example:

[[headers]]
  for = "/assets/*"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

This is especially useful for larger projects or monorepos.

Common caching strategies

HTML pages

HTML usually changes more often than assets, so cache it carefully.

Recommended:

/*
  Cache-Control: public, max-age=0, must-revalidate

This ensures users always get fresh HTML while still allowing CDN optimization.

Static assets (JS, CSS, images)

For hashed assets:

/assets/*
  Cache-Control: public, max-age=31536000, immutable

For non-hashed assets, lower the cache duration.

API responses

If you’re serving JSON or API-like responses:

/api/*
  Cache-Control: public, max-age=60

This allows short-term caching while keeping data reasonably fresh.

Security-related headers

Headers aren’t just for caching. You can also improve security.

Example:

/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

You can define these alongside caching rules.

Debugging caching issues

If changes don’t appear immediately:

  • Check the response headers in your browser’s dev tools
  • Verify the file path matches your rule
  • Make sure your build output actually includes _headers
  • Redeploy the site after changes

Netlify applies headers at deploy time, not dynamically.

When headers don’t apply

Headers won’t apply if:

  • The _headers file is not in the published directory
  • The path pattern doesn’t match the requested URL
  • Another rule overrides it later in the file

Order matters: more specific rules should come before generic ones.

Final thoughts

Correct caching can drastically improve performance, reliability, and user experience. Netlify gives you powerful tools to control it, without needing custom infrastructure or complex CDN setups.

Once you’re comfortable with headers, you can combine them with redirects, rewrites, and deploy previews to build fast, production-grade sites with confidence.

Manage Netlify on the go

Download Netli.fyi and monitor your sites, check deploys, and manage your projects from anywhere.

Related articles