How Does Caching Differ Between GraphQL and REST?
Learn why REST caches naturally via URLs while GraphQL needs normalized client caches or persisted queries instead.
Expected Interview Answer
REST caches naturally at the HTTP layer because each resource has a stable, unique URL that CDNs and browsers can key on, while GraphQL typically serves every query through one POST endpoint, so it needs application-level caching strategies like normalized client-side caches or persisted queries instead of relying on standard HTTP caching.
A REST GET request to /api/products/42 can be cached by a CDN, a browser, or a reverse proxy using standard Cache-Control and ETag headers, because the URL itself uniquely identifies the resource and its freshness window. GraphQL, however, usually sends every query as a POST with a body, and POST responses are not cached by default HTTP infrastructure, and even if they were, two different queries against the same endpoint URL would collide under one cache key. To compensate, GraphQL clients like Apollo or Relay build a normalized in-memory cache keyed by each object's typename and ID, so overlapping fields across different queries are deduplicated and reused client-side without a network round trip. Some teams also adopt persisted queries โ sending a query hash instead of the full query body, over GET โ specifically to regain CDN-level caching for GraphQL, and server-side response caching keyed by the resolved query plus variables is another common mitigation, though it requires more deliberate engineering than REST's cache-for-free-by-URL model.
- REST: standard Cache-Control/ETag headers cache automatically at CDN, proxy, browser
- GraphQL: normalized client caches (Apollo, Relay) deduplicate overlapping fields across queries
- Persisted queries let GraphQL regain GET-based CDN caching when needed
- Server-side query+variables caching mitigates GraphQL's lack of URL-based caching
AI Mentor Explanation
REST caching is like a stadium printing a fixed scoreboard poster per match number that any kiosk can photocopy and reuse instantly for repeat requests. GraphQL caching is like a scorer answering custom spoken questions each time, so no poster exists to photocopy, and instead the scorer keeps a private notebook of facts already given out, reusing overlapping facts across different questions without redoing the calculation. That fixed-poster-vs-custom-notebook distinction is exactly why REST caches at the network layer while GraphQL needs a smarter client-side cache.
Step-by-Step Explanation
Step 1
REST: request hits a stable URL
CDNs and browsers cache the response keyed by that URL using Cache-Control and ETag headers.
Step 2
GraphQL: request is a POST query body
The single endpoint URL cannot distinguish between different queries, so standard HTTP caching does not apply directly.
Step 3
Client normalizes responses locally
Apollo/Relay-style caches store objects by typename+ID, deduplicating overlapping fields across different queries.
Step 4
Optional persisted queries or server caching
Sending a query hash over GET, or caching by resolved query+variables server-side, restores CDN/HTTP-level caching for GraphQL.
What Interviewer Expects
- Clear explanation of why REST caches naturally via URL-keyed HTTP caching
- Understanding that GraphQL's single POST endpoint defeats default HTTP caching
- Mention of normalized client-side caching (Apollo/Relay) as GraphQL's mitigation
- Awareness of persisted queries as a technique to regain CDN caching for GraphQL
Common Mistakes
- Claiming GraphQL simply cannot be cached at all
- Forgetting that GraphQL typically uses POST, which standard caches skip
- Not mentioning normalized client caches as GraphQL's primary caching strategy
- Assuming REST caching requires no special headers beyond a stable URL
Best Answer (HR Friendly)
โREST is easy to cache because each resource has its own web address that a browser or CDN can remember and reuse. GraphQL usually sends every request to the same address with different content, so it cannot be cached the same simple way โ instead, GraphQL apps keep a smart local cache of data they already fetched, or use tricks like sending a short code instead of the full query so it behaves more like a cacheable REST request.โ
Code Example
// REST: cacheable by URL, standard HTTP caching applies
app.get('/api/products/:id', (req, res) => {
res.set('Cache-Control', 'public, max-age=300')
res.json(getProduct(req.params.id))
})
// GraphQL: single endpoint, client must normalize manually
const cache = new Map() // key: `${typename}:${id}`
function readFromCache(typename, id) {
return cache.get(`${typename}:${id}`)
}
function writeToCache(objects) {
for (const obj of objects) cache.set(`${obj.__typename}:${obj.id}`, obj)
}
// Two different queries sharing a Product field reuse the same cache entry
// instead of each hitting the network separately.Follow-up Questions
- What are persisted queries and how do they help GraphQL caching?
- How does a normalized cache like Apollo InMemoryCache decide when data is stale?
- How would you cache a GraphQL response server-side by query and variables?
- What is the tradeoff of moving GraphQL queries to GET requests for cacheability?
MCQ Practice
1. Why does REST cache more naturally at the HTTP layer than GraphQL?
A stable URL per resource lets standard HTTP caching infrastructure work automatically for REST.
2. What is the standard client-side mitigation for GraphQL's caching gap?
Clients like Apollo and Relay maintain a normalized store so overlapping fields across queries are reused.
3. What technique lets GraphQL regain CDN-level HTTP caching?
Persisted queries replace the POST body with a short hash sent via GET, restoring URL-based cacheability.
Flash Cards
Why does REST cache easily? โ Stable, unique URLs per resource that HTTP infrastructure can key on.
Why is GraphQL harder to cache at the HTTP layer? โ Every query typically goes through one POST endpoint, defeating URL-based caching.
GraphQL's standard caching mitigation? โ A normalized client-side cache keyed by typename+ID (Apollo, Relay).
Technique to regain CDN caching for GraphQL? โ Persisted queries sent as a hash over GET.