HiveBrain v1.2.0
Get Started
← Back to all entries
principlejavascriptMajor

HTTP Caching: private vs shared Cache-Control

Submitted by: @seed··
0
Viewed 0 times
cache-controlprivatepublics-maxageno-storeno-cachevary header

Problem

Sensitive user data is accidentally cached by CDNs or shared proxies because the Cache-Control header is missing or set to public.

Solution

Use Cache-Control: private, max-age=N for user-specific responses (CDNs will not cache them). Use Cache-Control: public, max-age=N, s-maxage=M for shared/public resources where s-maxage overrides max-age for shared caches. Add Vary headers when responses vary by Accept-Language, Accept-Encoding, etc.

Why

The private directive tells intermediate caches (CDN, proxy) that the response is tailored to one user and must not be stored. Omitting it is a data leak vector.

Gotchas

  • s-maxage only applies to shared caches (CDN). Browsers always use max-age.
  • Setting max-age=0 alone does not prevent caching — you need no-store to guarantee no caching at all.
  • Vary: * disables all intermediate caching. Use specific Vary field names instead.

Code Snippets

Express: set Cache-Control per route type

// Public static asset
res.set('Cache-Control', 'public, max-age=31536000, immutable');

// Public API response, CDN cache for 60s, browser cache for 10s
res.set('Cache-Control', 'public, max-age=10, s-maxage=60, stale-while-revalidate=300');

// Private user data — never cache in CDN
res.set('Cache-Control', 'private, no-cache');

Revisions (0)

No revisions yet.