Skip to content
DevOps AI ToolKit
Newsletter
All prompts
AI for NGINX Difficulty: Intermediate ClaudeChatGPTCursor

NGINX Static-Asset Cache-Control & Immutable Versioning Prompt

Generate a correct static-asset caching policy for NGINX — long-lived immutable caching for fingerprinted bundles, short/revalidated caching for HTML, and no accidental caching of authenticated responses — so browsers and CDNs stop re-downloading unchanged files without ever serving stale HTML.

Target user
Engineers serving front-end assets or SPA builds directly from NGINX
Difficulty
Intermediate
Tools
Claude, ChatGPT, Cursor

The prompt

You are a senior web-performance engineer who tunes NGINX static-asset caching for real front ends. You know the golden rule — cache fingerprinted assets forever, never cache the HTML that references them — and you know that `expires`/`Cache-Control` and CDN behavior interact. You comment every directive and you never emit a policy that risks pinning stale HTML in users' browsers.

I will provide:
- How assets are built and named (content-hashed filenames like `app.4f3c9a.js`? unversioned?): [DESCRIBE]
- The document root and the URL paths for HTML vs static assets: [DESCRIBE]
- Whether a CDN sits in front of NGINX: [DESCRIBE]
- Whether any responses are user-specific / authenticated: [DESCRIBE]
- Framework specifics (SPA index fallback, service worker, etc.): [DESCRIBE]

Do this:

1. **Split by content type, not by guesswork.** Produce `location` blocks that match fingerprinted assets (by extension and/or hashed-name pattern) separately from HTML. Explain why a single blanket `expires` on the whole root is the classic mistake.

2. **Immutable for fingerprinted assets.** For content-hashed JS/CSS/fonts/images, set `expires 1y;` and `add_header Cache-Control "public, max-age=31536000, immutable";`. Explain how `immutable` stops needless revalidation and why it is only safe when the filename changes on every content change.

3. **Short + revalidated for HTML.** For `index.html` / documents, set `add_header Cache-Control "no-cache";` (or a short `max-age` with `must-revalidate`) so a new deploy is picked up immediately. Explain the "cache the map forever, but always re-check the index" model.

4. **Never cache private responses.** For any authenticated or user-specific path, force `Cache-Control "private, no-store"` and explain the risk of a shared CDN caching one user's response for another.

5. **Make the headers actually apply.** Warn about the `add_header` inheritance trap: adding a header in a nested `location` drops all inherited `add_header` directives, and `add_header` is skipped on some error responses — show the correct placement (and `always` where needed).

6. **CDN alignment.** If a CDN is present, note how `Cache-Control` drives edge TTLs, and when to add `Vary` (e.g., `Accept-Encoding`) so compressed and uncompressed variants are not cross-served.

Output: (a) the complete, commented `server {}` with the asset and HTML `location` blocks; (b) a table mapping each content class to its `Cache-Control` value and the reasoning; (c) verification commands using `curl -sI` to confirm the exact `Cache-Control`/`Expires` headers on a hashed asset, on `index.html`, and on an authenticated path; and (d) a note on how to bust a bad policy already cached in browsers. Treat the config as a reviewable artifact: validate with `nginx -t` and reload, never edit the live file in place.

Run this prompt with AI

Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.

Why this prompt works

Static-asset caching has exactly one way to go badly wrong at scale: you long-cache something that is not content-hashed, and now stale HTML or an old bundle is pinned in thousands of browsers with no clean invalidation. This prompt hard-codes the golden rule — immutable, year-long caching only for fingerprinted assets, and no-cache/short revalidation for the HTML that references them — so the safe policy is the default, not an afterthought.

It also catches the single most confusing NGINX caching bug: the add_header inheritance trap, where adding a header in a nested location silently drops every inherited add_header, so your carefully written Cache-Control just disappears. By making that an explicit warning with correct placement and always, the prompt prevents a config that looks right but ships no cache headers at all.

Because it ends with concrete curl -sI checks on a hashed asset, on index.html, and on an authenticated path, you verify the exact headers users receive rather than trusting the config. The private/no-store rule for authenticated responses closes the last dangerous gap — a shared CDN caching one user’s response for another.

Related prompts

More NGINX prompts & error guides

Browse every NGINX prompt and troubleshooting guide in one place.

Free download · 368-page PDF

Reading prompts? Get all 500 in one free PDF

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.