REST Cacheability and Cache-Control Headers
Fast recall
Quick revision
Core answer
Cache-Control sets storage and freshness policy, Vary separates negotiated variants, and validators such as ETag or Last-Modified support conditional revalidation. no-cache means revalidate before reuse; no-store means do not store the response.Interview-ready guide
Interview answer
Cacheability in REST means a client cache or intermediary can store a response and reuse it when HTTP rules allow. Reusing a response can reduce latency, bandwidth, and work at the origin service. It is different from an internal Spring or database cache because HTTP metadata tells components outside the application whether the transferred response is safe to retain and reuse.
Cache-Control carries the main policy. max-age=60 normally makes a stored response fresh for 60 seconds. no-cache permits storage but requires validation before reuse, while no-store tells caches not to store the response. private limits storage to a private cache such as a browser; public explicitly permits shared-cache storage in cases where that policy is appropriate.
The origin can return an opaque validator such as ETag: "product-42-v7". After the response becomes stale, the client sends If-None-Match: "product-42-v7". If the selected representation is unchanged, the origin returns 304 Not Modified without another response body, and the cache reuses its stored copy. Last-Modified with If-Modified-Since provides a time-based alternative with lower precision.
A public product catalogue may use shared caching, while an account response usually needs private or no-store according to its sensitivity. Vary names request headers that selected the representation. For example, Vary: Accept-Encoding keeps compressed and uncompressed responses in separate cache entries. Missing Vary can serve the wrong variant; naming too many fields can reduce the cache hit rate.
A cache rule must reflect how stale the data may be, who may receive it, and which request selected it. Statelessness alone does not make a response cacheable, and a framework cache annotation does not create a correct HTTP contract. Test the actual method, status, headers, mutation path, and revalidation response. Fast reuse is useful only when the cache cannot leak personalized data or return an unacceptable old representation.
REST Cacheability and Cache-Control Headers
Direct Answer
Cacheability in REST means a client or intermediary may reuse a stored response when HTTP rules permit. Cache-Control sets storage and freshness policy, Vary separates negotiated variants, and validators such as ETag or Last-Modified support conditional revalidation. no-cache means revalidate before reuse; no-store means do not store the response.
Deep Dive & Architecture
A response can be storable yet not reusable immediately. Storage rules decide whether a cache may retain it. Freshness decides whether it can be reused without contacting the origin. A stale response might become reusable after validation, and some rules allow controlled stale use. Keeping these concepts separate prevents the common no-cache versus no-store mistake.
An ETag is an opaque validator selected by the origin. A strong validator identifies byte-equivalent representations for operations that require strong comparison; a weak ETag can support semantic cache validation but is not suitable for every range or precondition use. Last-Modified is easier but has time-resolution limits and may be unavailable.
Vary changes the cache key by naming request fields that selected the response. Omitting it can serve the wrong language, encoding, or media type. Using Vary: * prevents normal reuse and broad Vary values reduce hit rate, so it should reflect actual selection inputs.
Caching authenticated and personalized data needs deliberate policy. Shared caches normally cannot reuse a response to an authorized request unless response directives permit it. Private caches and shared caches have different audiences. Test behavior with real headers, mutations, and revalidation instead of assuming a framework annotation creates a correct cache contract.
Code Example
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=60, must-revalidate
ETag: "product-42-v7"
Vary: Accept-Encoding
{"id":42,"priceMinor":1999}
GET /products/42 HTTP/1.1
If-None-Match: "product-42-v7"
HTTP/1.1 304 Not Modified
After freshness expires, the validator can avoid retransmitting the representation. must-revalidate limits stale reuse; it does not mean the response must be checked while still fresh.
Check your understanding
Answer these without looking back at the article.
- What is the difference between `no-cache` and `no-store`?
- How does an ETag reduce data transfer during revalidation?
- Why can a missing `Vary` header serve the wrong representation?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.