Cache-Control headers kiểm soát caching behavior: max-age (duration), no-cache (revalidate before use), no-store (never cache); ETag và Last-Modified cho conditional requests.
Cache-Control directives:
- max-age=3600: cache valid trong 3600 giây, không cần request lại server
- no-cache: cache phải validate với server trước khi dùng (dùng ETag/Last-Modified) — không có nghĩa là 'không cache'
- no-store: không cache ở bất kỳ đâu (sensitive data, banking)
- public: CDN và browser đều có thể cache
- private: chỉ browser cache (không CDN) — response personalized
- s-maxage=86400: override max-age chỉ cho shared cache (CDN)
- immutable: resource sẽ không thay đổi (content-hashed assets) — browser không revalidate
ETag (Entity Tag): server gửi hash của content trong response header. Lần sau client gửi If-None-Match: "hash", server so sánh: nếu match → 304 Not Modified (không gửi body); nếu changed → 200 với body mới.
Last-Modified: tương tự nhưng dùng timestamp thay vì hash — kém chính xác hơn ETag. Best practice: static assets với content hash → max-age=31536000, immutable; HTML/API → no-cache với ETag.
Cache-Control headers control caching behavior: max-age (duration), no-cache (revalidate before use), no-store (never cache); ETag and Last-Modified enable conditional requests.
Cache-Control directives:
- max-age=3600: cache is valid for 3600 seconds, no need to contact the server
- no-cache: the cache must revalidate with the server before using the cached copy (using ETag/Last-Modified) — does NOT mean 'do not cache'
- no-store: do not cache anywhere (for sensitive data such as banking)
- public: both CDN and browser may cache the response
- private: browser cache only (not CDN) — for personalized responses
- s-maxage=86400: overrides max-age for shared caches (CDN) only
- immutable: the resource will never change (content-hashed assets) — the browser skips revalidation
ETag (Entity Tag): the server sends a hash of the content in the response header. On the next request the client sends If-None-Match: "hash"; the server compares: if it matches → 304 Not Modified (no body); if changed → 200 with a new body.
Last-Modified: similar but uses a timestamp instead of a hash — less precise than ETag. Best practice: static assets with content hashes → max-age=31536000, immutable; HTML/API responses → no-cache with ETag.