The Cache-Control directives no-cache, no-store and private sound similar, but they answer different questions. no-cache requires validation before reuse. no-store tells caches not to store the response. private allows storage in a user’s private cache but excludes shared caches.

Choosing by name alone is how sensitive responses get stored or useful responses lose all caching.

The short comparison

Directive May a cache store the response? May it be reused without validation? May a shared cache store it?
no-cache Yes No Yes, unless another directive forbids it
no-store No No No
private Yes Depends on other directives No

These directives can be combined with controls such as max-age, must-revalidate and validators. The complete policy matters more than any one word.

no-cache means revalidate

Despite its name, no-cache does not prohibit storage. A browser or intermediary may keep the response, but it must validate the stored copy with the origin before using it again.

That makes no-cache useful when transferring the full representation is expensive but the server must decide whether the stored copy remains current. With an ETag, the next request can send If-None-Match. The origin may answer 304 Not Modified, avoiding another full body.

Read ETag vs Last-Modified for the validator side of that exchange.

A response can state:

Cache-Control: no-cache
ETag: "report-42-v7"

The cache stores the report, asks before reuse, and can use a lightweight validation response when nothing changed.

no-store means do not retain it

no-store tells private and shared caches not to store the response. It is the stronger choice for responses that should not persist in caches, such as highly sensitive account or authentication data.

A typical header is:

Cache-Control: no-store

This is not a guarantee that information disappears from every system. Application logs, analytics, browser history, screenshots, crash reports and other storage layers are separate concerns. no-store is a cache directive, not a complete data-handling policy.

MDN also warns that no-store does not delete a response that was stored before the directive was introduced. Changing a header today does not erase old copies automatically.

private limits shared caching

private permits storage by a private cache, usually the end user’s browser, while preventing storage in shared caches such as many CDN or proxy caches.

For a personalized dashboard response, a policy might be:

Cache-Control: private, no-cache

The browser may keep the response but must validate it before reuse. A shared cache must not store it.

private alone does not require revalidation. If the response also has a freshness lifetime, the browser can reuse it while fresh. Decide separately who may store it and when it may be reused.

Why public and s-maxage matter

Shared-cache behavior can be stated explicitly with public and s-maxage.

  • public allows a shared cache to store a response even when it would not normally be cacheable.
  • s-maxage sets a freshness lifetime for shared caches and overrides max-age there.
  • private excludes shared storage.

For example:

Cache-Control: public, max-age=60, s-maxage=300

A browser can treat the response as fresh for 60 seconds, while a shared cache can keep it fresh for 300 seconds. That policy suits some public API or page responses, not individualized data.

Authentication does not decide the policy for you

A request carrying Authorization changes the shared-cache rules, but it does not remove the need for an explicit response policy. Do not assume that authentication automatically makes every response safe from intermediary storage.

Classify the response:

  • Is the body identical for every authorized user?
  • Does it contain user-specific or confidential data?
  • Can a browser keep it?
  • Can a shared cache keep it?
  • How stale may it become?
  • Is validation required before every reuse?

Turn those answers into directives and tests.

Request and response directives differ

Clients can send request directives such as no-cache to ask intermediaries to validate a stored response. That does not rewrite the origin’s response policy. A forced refresh in developer tools is a request behavior, not proof that production responses are configured correctly.

Inspect the final response after every proxy and CDN. Framework defaults, reverse-proxy rules and edge functions can add, merge or replace cache headers.

Common mistakes

Using no-cache for secrets

no-cache still allows storage. Use no-store when the cache must not retain the response.

Using no-store everywhere

Blanket no-store disables useful caching and validator-based revalidation. It increases latency and origin load even for public, reusable content.

Adding private without a freshness rule

private controls which caches may store the response. It does not by itself say how long a browser can reuse it.

Setting contradictory directives in different layers

An application might send private while a CDN configuration adds public, s-maxage=600. Test the effective header at the public URL, not just the framework object before it reaches the network.

Treating cache busting as invalidation

Changing an asset URL avoids reuse of the old URL, but the old object may still remain in caches until it expires or is purged. URL versioning and cache invalidation solve related but different problems.

A production test matrix

For every important route, test:

  1. an anonymous request and an authenticated request;
  2. the first response and an immediate repeat;
  3. behavior through the real CDN;
  4. a conditional request with If-None-Match or If-Modified-Since;
  5. a response after content changes;
  6. two different users requesting the same path;
  7. a browser back/forward navigation where relevant.

Record the final Cache-Control, Age, ETag, Last-Modified, Vary and status fields. A policy is not complete until the intermediary behavior matches the header.

A safer selection rule

Use no-store when storage itself is unacceptable. Use private when browser storage is acceptable but shared storage is not. Use no-cache when storage is acceptable but reuse requires validation. Combine directives only when each one expresses a deliberate, testable part of the policy.

Sources and version note

This guide was checked on October 27, 2026 against MDN’s Cache-Control reference. CDN products and frameworks can add their own behavior, so verify their current documentation and inspect the final public response.