Persisted Queries
Persisted queries let clients execute a query by its hash instead of sending the full query text on every request. The benefits compound:
- Performance — requests shrink from kilobytes of query text to a short hash, and GET requests with hashes are CDN-cacheable.
- Security — with static registration, the persisted set becomes an allowlist: the endpoint executes known queries only, eliminating arbitrary query execution.
Brightspot supports the two standard flavors on every endpoint via the PersistedQueryProtocol configured on the endpoint (the Persisted Query Protocol field editorially).
Automatic Persisted Queries (APQ)
APQ is the Apollo-standard protocol: clients register queries on the fly, keyed by SHA-256 hash.
- The client sends only the hash in the request extensions:
1{2"extensions": {3"persistedQuery": {"version": 1, "sha256Hash": "ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}4}5}
- If the endpoint doesn't recognize the hash, it responds with a
PersistedQueryNotFounderror. - The client retries once with both the hash and the full
querytext; the endpoint validates the hash, stores the pair, and executes. - All subsequent requests—from any client instance—use the hash alone.
Registered queries are stored per endpoint (and per client where applicable) and cached for fast lookup. Apollo Client, urql, and most GraphQL clients support APQ out of the box—enable their persisted-queries link and point them at your endpoint.
APQ is a performance feature: any query can still be registered by anyone who can call the endpoint, so it does not restrict what can be executed.
Static persisted queries
Static persisted queries are registered ahead of time, and the endpoint will not accept unregistered queries via the protocol—this is the allowlist mode. The registry is a JSON mapping (hash → query text) managed through the CMS and stored with the endpoint. A typical workflow:
- At client build time, extract the queries your application uses and compute their hashes (standard tooling from the persisted-queries ecosystem works).
- Upload/register the mapping in the CMS for the endpoint.
- Clients send only hashes, exactly as in APQ—but a hash that isn't in the registry is rejected rather than registered.
Because queries can't be registered dynamically, deploys that introduce new queries must update the registry first (register, then roll out the client).
Choosing between them
| APQ | Static | |
|---|---|---|
| Setup | None—clients self-register | Registry maintained per release |
| Performance | ✓ | ✓ |
| Restricts executable queries | ✗ | ✓ |
| Best for | Internal apps, fast iteration | Public, high-exposure endpoints |
A pragmatic progression: start with APQ during development, switch the endpoint to static registration as part of production hardening.
Operational notes
- Registered queries are visible in the CMS, so you can audit exactly what each endpoint will execute.
- Hash lookups are cached; registration uses distributed locking so concurrent first-registrations are safe.
- Persisted queries compose with everything else—complexity budgets, analytics, and the @debug directive all behave identically.
Next steps
- Security — where allowlisting fits in your security posture
- GraphQL Explorer — for developing the queries you'll persist