Skip to content

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

  1. 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.
  2. Normalisation. The server normalises the query (strips whitespace/formatting, canonicalises operation selection) before hashing, so semantically-identical queries land on the same ID.
  3. Bundle IDs, not text. The UI bundle ships with the IDs embedded in place of the query strings.
  4. Runtime request. The client sends {"id": "<hash>", "variables": {...}} instead of {"query": "...", "variables": {...}}.
  5. 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, field X can 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

Last updated · 501 distilled / 1,218 read