Nginx · The edge of your stack

How does browser and HTTP caching work with Nginx?

Mediumcachingcache-controletagUpdated Oct 2026
Quiz this track

Short answer

Nginx sets response headers such as Cache-Control and ETag. Long immutable caching suits hashed assets, while HTML should revalidate so users get new asset references after a deploy.

This is client-side caching, not proxy caching. The browser decides whether to reuse a response based on Cache-Control, Expires, ETag and Last-Modified. A deploy-safe strategy is content-hashed filenames with immutable caching and short-lived HTML.

nginx
location ~* \.(?:css|js|woff2|png|jpg|jpeg|svg)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    access_log off;
}

location = /index.html {
    add_header Cache-Control "no-cache";
}
Hashed assets can be cached for a year; HTML revalidates so new asset names are discovered.

Header semantics

  • max-age is measured in seconds; immutable says the file will not change at that URL
  • no-cache allows storage but requires revalidation before reuse
  • no-store tells clients and intermediaries not to store the response
  • ETag or Last-Modified enables a 304 response when content is unchanged
  • Vary: Accept-Encoding keeps compressed and uncompressed variants separate
Do not apply immutable caching to filenames that change content in place. Users may keep the old file for a year with no way to invalidate it.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What is the difference between no-cache and no-store?
  2. 2Why is immutable caching safe for hashed assets?
  3. 3How does a 304 response reduce bandwidth?
  4. 4What happens if you cache HTML for a year?

Say it in the interview

I separate static assets from HTML. Hashed assets get a long max-age and immutable because their URL changes with the content, while HTML gets no-cache so the browser revalidates. I rely on ETag for cheap 304s and use Vary where the response depends on a request header. I never put immutable caching on URLs whose content can change in place.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Nginx mock interview and get scored feedback on depth, clarity and confidence.