How do Cache-Control and ETag headers work together?
Cache-Control says how long a response may be reused without asking. ETag is a fingerprint of the content; after expiry the browser sends it back, and the server replies 304 Not Modified if nothing changed, saving the download.
Explain it simply
When a server sends a response, it can attach rules for reuse.
Cache-Control: max-age=3600 tells the browser it may reuse this copy for an hour with no network request at all. Other values: no-store (never keep), no-cache (keep but always revalidate), public or private (shared caches may or may not store it).
ETag is a version label, often a hash of the content. When the hour ends, the browser does not blindly re-download. It sends If-None-Match with the stored ETag. The server compares:
- Same: reply 304 Not Modified with no body. The browser keeps its copy.
- Different: reply 200 with the new body and a new ETag.
A 304 is tiny, so revalidation costs one round trip but no payload. Last-Modified with If-Modified-Since works the same way using a date instead of a hash.
Example
Request 1:
GET /logo.png
<- 200 OK, ETag: "a1b2", Cache-Control: max-age=60
After 60 seconds:
GET /logo.png, If-None-Match: "a1b2"
<- 304 Not Modified (no body, about 200 bytes)What to say in the interview
"Cache-Control sets freshness lifetime; ETag enables cheap revalidation after that lifetime. A matching If-None-Match gets a 304 with no body. I use long max-age with hashed filenames for static assets, and no-cache with ETag for content that must always be current."