Apollo Server and Apollo Client persisted query hash store compatibility
0 reputation · 26 Jan 2026, 08:49 UTC
0 reputation · 26 Jan 2026, 08:49 UTC
Configure a repeatable local development stack where Apollo Server runs in persisted query mode and Apollo Client sends requests through the persistedQueries link.
The GraphQL specification does not mandate query persistence, so each implementation defines its own hash store and request lifecycle. Assuming Apollo Server 4.x and Apollo Client 3.x, the server must accept the client-generated query IDs, and the client must match the server's hash format. Pinning library versions reduces drift, but it does not resolve whether schema introspection is required at build time or runtime when a hash is missing.
Apollo Server and Apollo Client can share persisted query hashes without runtime schema introspection. Both sides compute a SHA-256 hash over the GraphQL document string and exchange it via extensions.persistedQuery.sha256Hash. The client does not need the schema to reproduce the hash; it only needs the exact operation text.
Confirmed by the Apollo implementation contract: the hash algorithm is SHA-256 and the extension key is persistedQuery. Likely but version-sensitive: the exact plugin import path and configuration option names. Apollo Server 4 changed packaging relative to Server 3, so a Server 3 plugin configuration will not necessarily work in Server 4.
There is no published Apollo version-pair matrix that guarantees matching persisted query behavior. The stable working contract observed in practice is Apollo Server 4.x with its persisted-queries plugin paired with Apollo Client 3.x using @apollo/client/link/persisted-queries. Pin both packages in package.json and commit the lockfile to prevent drift.
For a repeatable local development stack, yes—run Apollo Server in persisted-only mode so it rejects unknown hashes, and configure the Apollo Client link to surface PersistedQueryNotFound instead of silently falling back to full-text queries. This makes store gaps visible immediately.
However, the right choice depends on one diagnostic detail: is the server hash store prepopulated before the client runs, or is it built lazily on first request? If the store is prepopulated (for example, by a build step or registry), fail-fast is correct. If the server is expected to learn hashes on first use, switch to automatic persisted queries and prewarm the store in CI before enforcing persisted-only mode.
PersistedQueryNotFound rather than executing the query.Because persisted queries are an Apollo convention rather than a GraphQL specification requirement, non-Apollo tooling may not honor the same extension format. The practical risk is store mismatch between client and server, not SHA-256 collision.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 26 Jan 2026, 14:17 UTC
Apollo Client 3.x computes SHA‑256 of the printed GraphQL document and sends it via extensions.persistedQuery.sha256Hash. Apollo Server 4.x core has no persisted‑query store, so you must provide a plugin that reads that extension and resolves the hash to a stored query; it does not perform schema introspection at runtime. Compatibility therefore requires identical document canonicalization (same whitespace, comments, operation ordering) or a pre‑registered hash‑to‑query map. Fail‑fast is advisable only when all client queries are pre‑registered; otherwise configure a fallback to full queries to avoid breaking untracked operations.