no-cache for Personalized Content

Learn how to use no-cache and private directives to handle personalized content that must be fresh but can still benefit from conditional request optimization.

Use Cases

Detailed Explanation

Caching Personalized Content

Personalized pages — dashboards, profiles, recommendation feeds — cannot be cached in shared caches because they differ per user. But they CAN benefit from browser caching with revalidation.

The Recommended Header

Cache-Control: private, no-cache

This combination means:

  • private: Only the user's browser may cache (CDN must not)
  • no-cache: Browser must revalidate before serving

Why Not just no-store?

no-store forces a full download on every request. For a dashboard page that weighs 50KB but changes only occasionally, this wastes bandwidth. With no-cache:

  1. Browser sends If-None-Match: "etag-123"
  2. Server checks if content changed
  3. If unchanged → 304 Not Modified (0 bytes body)
  4. If changed → 200 OK with full response

On a typical dashboard, 80–90% of requests result in 304 responses, saving significant bandwidth.

Server-Side Requirements

For no-cache to work efficiently, your server must support:

  • ETag generation: A hash of the response content
  • If-None-Match handling: Compare the client's ETag with the current version
// Express.js example
app.get('/api/dashboard', (req, res) => {
  const data = getDashboardData(req.user);
  const etag = generateETag(data);

  if (req.headers['if-none-match'] === etag) {
    return res.status(304).end();
  }

  res.set('Cache-Control', 'private, no-cache');
  res.set('ETag', etag);
  res.json(data);
});

Avoid These Mistakes

  • Never use public with personalized content — CDN could serve User A's data to User B
  • Don't skip private — corporate proxies might cache authenticated responses
  • Always set Vary: Cookie if personalization depends on session cookies

Use Case

A SaaS dashboard shows user-specific metrics, notifications, and recent activity. Using 'private, no-cache' with ETag support, the dashboard page loads instantly from browser cache 85% of the time (304 response in 50ms). The remaining 15% of requests fetch updated content when metrics change. This approach gives users the perception of instant load times while guaranteeing they always see their latest data.

Try It — Cache-Control Builder

Open full tool