Skip to content
Deployment
Skill

/netlify-caching

Cache dynamic and static responses on Netlify's CDN from Functions, Edge Functions, and proxies. Use when you add caching or cache-control headers to a function response, tune cache TTL or stale-while-revalidate, set up the durable cache, vary a cache key by

From plugin
netlify-skills
5216 skills1 MCP

Claude Code

$ npx -y skills add netlify/context-and-tools --skill netlify-caching --agent claude-code

SKILL.md

netlify-caching.SKILL.md
name: netlify-caching
description: Cache dynamic and static responses on Netlify's CDN from Functions, Edge Functions, and proxies. Use when you add caching or cache-control headers to a function response, tune cache TTL or stale-while-revalidate, set up the durable cache, vary a cache key by query/header/cookie/country/language, purge or invalidate the cache by site or cache tag, use the programmatic Cache API (caches.open/match/put) or @netlify/cache helpers (fetchWithCache/cacheHeaders/getCacheStatus/purgeCache), speed up an expensive API call, add ISR or on-demand revalidation, or debug why a response is or isn't cached via the Cache-Status header.

Netlify caching

Cache-control header to reach for

Dynamic responses (Functions, Edge Functions, proxies) are **NOT cached by default**. You must opt in. Set `Netlify-CDN-Cache-Control` on the response:

import type { Context } from "@netlify/functions";

export default async (req: Request, context: Context) => {
  return new Response("Hello world", {
    headers: {
      'Netlify-CDN-Cache-Control': 'public, durable, max-age=60, stale-while-revalidate=120'
    }
  });
};

Header choice (most specific wins; `CDN-Cache-Control`/`Cache-Control` always pass downstream):

  • `Netlify-CDN-Cache-Control` applies to the Netlify CDN only. **Reach for this.**
  • `CDN-Cache-Control` applies to all CDNs that support it.
  • `Cache-Control` applies to any CDN or the browser.

**Legacy path to avoid:** On-demand Builders do **not** support these headers or `Netlify-Vary`. They use a TTL pattern and key on URL path only. Don't reach for ODBs in new code.

Footguns (read first)

  • **Static assets are fresh for up to a year.** A shorter `max-age` is ignored. They change only on a new deploy or manual purge.
  • **basic-auth on ANY page disables caching for the ENTIRE site.**
  • **`durable` is serverless-only.** It has no effect on Edge Function responses.
  • **Cache API silently drops responses over 10 MB.** `cache.put()` doesn't store them and later lookups miss. Compress the content or split it across multiple entries.
  • Never opt sensitive content out of automatic invalidation. It can stay publicly cached after deploys/firewall changes.

Directives

  • `public` caches the response. `private` caches it in the browser only, not in Netlify's shared cache. `no-store` prevents caching.
  • `s-maxage=N` sets seconds in Netlify's shared cache (overrides `max-age` there).
  • `max-age=N` sets seconds in any cache.
  • `stale-while-revalidate=N` serves stale for N seconds after expiry while revalidating in the background.
  • `durable` (serverless only) stores the response in Netlify's durable cache so other edge nodes reuse it instead of re-invoking the function.

Defaults when no header is set:

  • Static: `Netlify-CDN-Cache-Control: public, s-maxage=31536000, must-revalidate`
  • Dynamic: `Cache-Control: public, max-age=0, must-revalidate`

Cache key variation — `Netlify-Vary`

Comma-delimited instructions on the response; pipe-delimited value lists:

Netlify-Vary: query=item_id|page, country=es+de|us, cookie=ab_test|is_logged_in
  • `query=a|b` varies on a subset; bare `query` varies on all params. Keys are case-sensitive; param order is irrelevant.
  • `header=Device-Type|App-Version` supports custom and most standard headers.
  • `language=en|es+pt` uses `+` for groups. It is checked against `Accept-Language` with quality weighting.
  • `country=us|es+pt` uses GeoIP with ISO 3166-1 two-letter codes; `+` groups.
  • `cookie=ab_test|is_logged_in` targets specific keys, not the whole `Cookie` header.

**Cannot vary by header on:** `Accept*`, `Cache-Control`, `Connection`, `Content-Length`, `Cookie`, `Host`, `If-*`, `Range`, `Referer`, `Upgrade`, `User-Agent`. For language/cookie/format, use `Vary: Accept-Language`/`Vary: Cookie` or the specific `Netlify-Vary` instruction.

**Consistency rule:** a URL must return the same `Netlify-Vary` on every response. The first cached response's instructions win and later ones are ignored.

`Netlify-Vary` and standard `Vary` are both respected. Use `Vary` for format/encoding, and to pass instructions to an upstream CDN like Cloudflare.

Cache tags & opt-out

Tag responses for taggable purging:

Netlify-Cache-Tag: tag1,tag2,tag3
  • `Netlify-Cache-Tag` (Netlify CDN) wins over `Cache-Tag` (passed downstream). Some providers strip `Cache-Tag`, so set both when proxying through them.
  • Constraints: case-insensitive, UTF-8 only, ≤1024 chars/tag, ≤500 tags/response.

Opt a response out of automatic atomic-deploy invalidation with `Netlify-Cache-ID`. Values are comma-separated, auto-registered as cache tags for purging, and have a separate 500-ID limit:

Netlify-Cache-ID: cms-proxy,product,image

After opting out, purge on demand after relevant changes, e.g. redirect/proxy or function changes behind a `Netlify-Cache-ID`.

On-demand invalidation (purge)

Purge from a **deployed function or edge function** with `purgeCache` from `@netlify/cache`. The site and purge token are configured automatically. Purging covers everything cached for the site, including Cache API entries:

import { purgeCache } from "@netlify/cache";

export default async () => {
  await purgeCache(); // no args = purge everything for the site
  return new Response("Purged!", { status: 202 });
};

Purge by tag, optionally targeting a deploy/subdomain:

import { purgeCache } from "@netlify/cache";

export default async (req: Request) => {
  const cacheTag = new URL(req.url).searchParams.get("tag");
  if (!cacheTag) return;
  await purgeCache({
    tags: [cacheTag],
    deployAlias: "deploy-preview-11",
    domain: "early-access.company.com",
  });
  return new Response("Purged!", { status: 202 });
};

`purgeCache(options?)` options:

  • `tags`: tags to purge. Omit to purge the whole site. Tag purges apply to all deploys unless you target one.
  • `deployAlias` (e.g. `deploy-preview-11`): targets that alias on the p
Read more
@netlify
Ships withnetlify-skills

Public Netlify skills for AI coding agents. Each skill is a focused, factual reference for a Netlify platform primitive — designed to help agents build correctly on Netlify without needing to search docs.

5216 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
52
Star history of netlify/context-and-tools on GitHub, a chart by star-history.com

Other skills on netlify-skills.

netlify-blobs

netlify-blobs

Store and retrieve unstructured objects, files, and cache-like state on Netlify with the @netlify/blobs module. Use when…

netlify-config

netlify-config

Configure Netlify builds and routing via netlify.toml, _redirects, and _headers. Use when setting a build command or publish…

netlify-database

netlify-database

Zero-config Postgres for Netlify apps via @netlify/database — querying data from Functions/Edge Functions, writing schema…

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify13d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel2w16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

pinme2mo3.8k
@glitternetwork@glitternetworkInstall Skill

Questions about netlify-caching.

Which coding agents can use netlify-caching?
netlify-caching installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.