Skip to content

Cache Control Headers

DodaTech 2 min read

title: "Cache-Control Directives — max-age, no-cache, no-store, and More" description: "Cache-Control directives (max-age, no-cache, no-store, private, public, must-revalidate, s-maxage) govern how browsers and proxies cache HTTP responses." date: 2026-06-28 lastmod: 2026-06-28 weight: 13 tags: [apis, caching] }

Cache-Control directives provide fine-grained control over HTTP caching behavior, including freshness duration, storage restrictions, and revalidation requirements.

What You'll Learn

  • Common Cache-Control directives
  • Directive combinations and precedence
  • Shared vs private cache directives

Why It Matters

Cache-Control is the primary mechanism for HTTP caching. Understanding each directive prevents caching sensitive data and ensures correct cache behavior.

Directive Comparison

Directive Meaning Example
public Any cache can store Cache-Control: public, max-age=3600
private Browser-only cache Cache-Control: private, max-age=3600
no-cache Must revalidate with origin Cache-Control: no-cache
no-store Never cache Cache-Control: no-store
max-age=N Fresh for N seconds Cache-Control: max-age=300
s-maxage=N Proxy/CDN max-age Cache-Control: public, s-maxage=3600
must-revalidate Must check if stale Cache-Control: must-revalidate
immutable Never changes (static assets) Cache-Control: immutable, max-age=31536000

Code Examples

# Different Cache-Control strategies
@app.route('/api/products')
def list_products():
    # Public, cache for 5 minutes
    resp = jsonify(products)
    resp.headers['Cache-Control'] = 'public, max-age=300'
    return resp

@app.route('/api/users/me')
def current_user():
    # Private, browser only
    resp = jsonify({'id': current_user.id, 'email': current_user.email})
    resp.headers['Cache-Control'] = 'private, max-age=60'
    return resp

@app.route('/api/balance')
def get_balance():
    # Never cache
    resp = jsonify({'balance': get_user_balance()})
    resp.headers['Cache-Control'] = 'no-store'
    return resp

@app.route('/api/status')
def system_status():
    # Must revalidate every time
    resp = jsonify({'status': 'healthy'})
    resp.headers['Cache-Control'] = 'no-cache'
    return resp

@app.route('/api/config')
def site_config():
    # CDN caches for 1 hour, browser for 5 minutes
    resp = jsonify(config)
    resp.headers['Cache-Control'] = 'public, max-age=300, s-maxage=3600'
    return resp

Common Mistakes

1. Using no-cache When You Mean no-store

no-cache still stores the response; it just requires revalidation.

2. Missing s-maxage for CDNs

Without s-maxage, CDNs use max-age, which may be too short.

3. Conflicting Cache-Control Headers

Don't set both public and private — they cancel out.

4. Forgetting Immutable for Static Assets

Static files with hashed filenames should use immutable.

5. Using no-store on Public Endpoints

Public endpoints should use appropriate caching, not no-store.

Practice Questions

  1. What is the difference between no-cache and no-store?
  2. What does s-maxage do?
  3. When would you use must-revalidate?
  4. What does the immutable directive mean?
  5. Can you combine multiple Cache-Control directives?

Answers:

  1. no-cache stores but requires revalidation; no-store prevents all storage.
  2. It sets max-age specifically for shared caches (proxies, CDNs).
  3. When cached data must always be validated if stale, never served stale.
  4. The response never changes, so browsers don't revalidate.
  5. Yes, comma-separated: public, max-age=3600, must-revalidate.

Challenge: Analyze your API endpoints and assign the correct Cache-Control strategy for each: public, private, no-cache, or no-store.

FAQ

What happens if I set both max-age and s-maxage?

: s-maxage overrides max-age for shared caches. Browsers use max-age.

Is no-cache safe for sensitive data?

: No. Use no-store for sensitive data like auth responses.

Should I use Cache-Control for all responses?

: Yes. Every response should have an explicit Cache-Control directive.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro