CONCEPT Cited by 2 sources
GraphQL persisted queries¶
Definition¶
GraphQL persisted queries is the technique of registering each GraphQL query that an application might issue ahead of time (typically at UI build time) and replacing the query text in production requests with a stable ID (typically a hash of the normalised query). Runtime traffic carries the ID plus variables; the server looks up the query by ID and executes it.
The persisted-queries DB becomes the authoritative catalogue of what queries exist in this system — a closed, finite, inspectable set rather than a permissive GraphQL endpoint that accepts any well-formed query.
Mechanics¶
- Build-time persist step. When UI code is merged to main, the build pipeline extracts every query from the source, sends each to a persist endpoint on the GraphQL service, and receives an ID per query.
- Normalisation. The server normalises the query (strips whitespace/formatting, canonicalises operation selection) before hashing, so semantically-identical queries land on the same ID.
- Bundle IDs, not text. The UI bundle ships with the IDs embedded in place of the query strings.
- Runtime request. The client sends
{"id": "<hash>", "variables": {...}}instead of{"query": "...", "variables": {...}}. - Server-side lookup & execute. The GraphQL server resolves the ID to the registered query text and runs it.
Two enforcement modes¶
The mechanism is the same; organisations differ on what to do when a request arrives with an unknown ID:
- Cache mode (Apollo APQ). An unknown ID triggers a round-trip: the client retries with the full query text; the server caches it under the supplied hash. Optimisation for bandwidth and cache-friendliness; the endpoint still accepts raw queries.
- Gate mode (Zalando UBFF). An unknown ID is rejected. Raw queries are not accepted at the production endpoint at all. The persisted-queries DB is the only source of executable queries. See patterns/disable-graphql-in-production (Source: sources/2022-02-16-zalando-graphql-persisted-queries-and-schema-stability).
The gate-mode property is what unlocks schema-usage observability: with the production query set closed and finite, the server can enumerate for every schema field "which query IDs reference you, if any?" — the basis for concepts/graphql-schema-usage-observability.
Why organisations adopt it¶
- Bandwidth reduction. IDs are O(1-char) vs. O(full-query-text); APQ was originally motivated by mobile bandwidth.
- Safe breaking changes. If no production query
references field
X, fieldXcan be removed or retyped without breaking any client (Source: sources/2022-02-16-zalando-graphql-persisted-queries-and-schema-stability). - Query-level monitoring. Each persisted query has a stable identity, so SLOs, p99 dashboards, error rates, and alerts can be per-query.
- Shrinks attack surface. Arbitrary GraphQL queries are a well-known DoS vector (deeply-nested recursive queries, expensive resolvers). Gate mode makes that class of attack impossible at the endpoint.
Seen in¶
- Zalando UBFF — the canonical gate-mode instance.
Combined with
@draft/@allowedFordirectives, the persisted-queries DB becomes the single source of truth for what the graph is doing in production (sources/2022-02-16-zalando-graphql-persisted-queries-and-schema-stability, systems/zalando-graphql-ubff). - Zalando Fashion Store Rendering Engine — APQ is on-by-default for the Rendering Engine's GraphQL calls, reducing request size (sources/2021-09-08-zalando-micro-frontends-from-fragments-to-renderers-part-2).
- Apollo Server — the cache-mode reference implementation in the Apollo ecosystem (cited by the Zalando post as the peer approach).
Related¶
- patterns/automatic-persisted-queries — the canonical pattern page; gate-mode and cache-mode are its two instances.
- patterns/disable-graphql-in-production — the framing that turns gate-mode into a design principle.
- concepts/graphql-schema-usage-observability — what you get once the production query set is closed.
- concepts/draft-schema-field — the
@draftdirective that makes draft fields unpersistable in gate mode. - concepts/component-scoped-field-access — the
@component+@allowedFordirectives that restrict which queries may persist with an experimental field. - systems/graphql
- systems/zalando-graphql-ubff