What are persisted queries in GraphQL and why are they used?
Persisted queries send a hash instead of the full GraphQL query, shrinking payloads, enabling CDN caching, and allowlisting approved operations for security.
Expected Interview Answer
Persisted queries are a technique where a GraphQL operation is registered and referenced by a short hash instead of sending the full query string on every request, reducing payload size and letting the server allowlist exactly which operations it will run.
With Automatic Persisted Queries (APQ), the client first sends only a SHA-256 hash of the query; if the server recognizes it, it executes immediately, and if not, the client retries once with the full query so the server can store the hash-to-query mapping. This shrinks request bodies, improves CDN caching (GET requests keyed by hash), and — when combined with a fixed manifest — hardens security by rejecting any operation not on the approved list.
- Smaller request payloads (hash instead of full query)
- Enables GET requests and CDN edge caching
- Allowlist blocks arbitrary/malicious queries
- Lower bandwidth on mobile networks
- Faster parsing when queries are pre-registered
AI Mentor Explanation
Instead of a captain reciting an entire field-setting plan over the radio before every ball, the team pre-registers each plan with a codename, then just calls 'Plan Delta' and everyone knows the full arrangement. Persisted queries work the same way — a short hash stands in for a long, pre-agreed query, saving airtime and ensuring only sanctioned plans are ever run.
Step-by-Step Explanation
Step 1
Hash the operation
The client computes a SHA-256 hash of the exact query string.
Step 2
Send hash only
It sends just the hash under extensions.persistedQuery, omitting the full query.
Step 3
Server lookup
If the server knows the hash, it executes the stored query immediately.
Step 4
Register on miss
On a PersistedQueryNotFound error, the client retries with hash plus full query so the server caches it.
Step 5
Serve future hits fast
Subsequent clients send only the hash; GET requests become CDN-cacheable by hash.
What Interviewer Expects
- The hash-instead-of-query core idea
- The APQ two-step miss/register handshake
- How persisted queries enable GET + CDN caching
- Security benefit of an operation allowlist
- Distinction between automatic (APQ) and manifest-based persisted queries
Common Mistakes
- Confusing persisted queries with server response caching
- Thinking the hash carries the query content itself
- Forgetting the retry-with-full-query step on a cache miss
- Assuming APQ alone is an allowlist (it isn't without a fixed manifest)
- Believing they change what data is returned rather than how it's sent
Best Answer (HR Friendly)
“Persisted queries let the app send a short code (a hash) instead of the whole GraphQL query every time. This makes requests smaller and faster, allows caching, and lets the server accept only the pre-approved queries, which improves both performance and security.”
Code Example
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries'
import { sha256 } from 'crypto-hash'
const persistedLink = createPersistedQueryLink({
sha256,
// Prefer GET for cache hits so a CDN can cache by hash
useGETForHashedQueries: true,
})
const client = new ApolloClient({
// First request: hash only. On PersistedQueryNotFound,
// Apollo retries once with the full query to register it.
link: persistedLink.concat(new HttpLink({ uri: '/graphql' })),
cache: new InMemoryCache(),
})// POST body sent on the first (hash-only) attempt
{
"operationName": "GetUser",
"variables": { "id": "42" },
"extensions": {
"persistedQuery": {
"version": 1,
"sha256Hash": "ecf4edb46..."
}
}
}
// If unknown -> { errors: [{ message: 'PersistedQueryNotFound' }] }
// Client then resends the same body plus the full "query" string.Follow-up Questions
- How do APQ and a fixed persisted-query manifest differ for security?
- Why does useGETForHashedQueries improve CDN caching?
- What happens on a hash collision or a tampered hash?
- How would you roll out a new query version without breaking old clients?
MCQ Practice
1. What does the client send first in Automatic Persisted Queries?
APQ sends only the hash first; the full query is sent only if the server doesn't recognize it.
2. What does the server return when it doesn't recognize the hash?
PersistedQueryNotFound signals the client to retry with the full query to register it.
3. A key security benefit of a manifest-based persisted query setup is:
A fixed manifest lets the server reject any operation not on the approved list.
Flash Cards
What is a persisted query? — A GraphQL operation referenced by a short hash instead of its full text.
What is APQ's two-step handshake? — Send hash; on PersistedQueryNotFound, resend hash plus full query to register it.
Why enable GET for hashed queries? — GET requests keyed by hash can be cached at the CDN edge.
What security benefit do they add? — A fixed manifest allowlists only approved operations, blocking arbitrary queries.
APQ vs manifest persisted queries? — APQ auto-registers on demand; a manifest is a fixed, pre-approved allowlist.