Skip to content

Coming from another CDN

If you already run an API behind an edge cache, plain HTTP or GraphQL, most of what you configured there has a counterpart in GraphPilot. This page maps the usual concepts, points out where GraphPilot behaves differently, and ends with a checklist for moving traffic over.

What you have todayIn GraphPilotRead
Cache rules or TTL settings per pathA Cache-Control header from your originFrom the origin header
Cache rules or TTL settings per GraphQL type or field@cacheControl in your schema, or a Cache-Control header from your origin (which wins when it sets a lifetime or forbids storing)How long an entry lives
A lifetime in Surrogate-Control or ExpiresCache-Control. GraphPilot reads only Cache-Control; use s-maxage for a lifetime that only shared caches applyFrom the origin header
A stale window, serving old content while refreshingstale-while-revalidate from your origin, or swr on @cacheControlStale windows
Caching per user or per sessionThe private cache policy, which names what identifies one caller, with Cache-Control: private from your origin or scope: PRIVATE in your schemaIdentifying callers, authenticated requests
Caching per customer or per organizationA named scope such as ORGANIZATION on your GraphQL types, or a vary rule on the organization claim, so each group shares one entryNamed scopes, vary rules
Varying the cache on a header, cookie or query parameterYour origin’s Vary, or vary rules in the configIdentifying callers
Bypassing the cache for previews or editorsThe bypass cache policyBypass
Cache tags your origin sets on a responseA Surrogate-Key header on your origin’s responseThe Surrogate-Key header
Purging by tag, by URL or everythingThe purge API and gpilot purge: by surrogate key, by cache key (ck:GET:/products/42 for one path), by request, or allThe purge API
Key fields, and purging a GraphQL entity when it changesSurrogate keys derived from your schema’s key fields, purged automatically when a mutation returns the object; @surrogateKey for keys of your ownSurrogate keys, automatic invalidation
Cache debug headersgp-cache (HIT, MISS, PASS, STALE), gp-cache-reason, and the opt-in gp-surrogate-keyHeaders, debugging surrogate keys
APQ, persisted or trusted documentsPersisted queries: APQ, and a registry you push from your client’s manifest, which can refuse anything it does not holdPersisted queries
JWT checks at the edgeAuthentication providers in the configAuthentication
An IP allowlist or a shared secret at the originPublished edge IP ranges, and a signature on every forwarded requestOrigin allowlist, request signing
A header that sets the browser’s or a downstream CDN’s lifetimeThe downstream Cache-Control header GraphPilot can writeDownstream header
Your own hostnameCustom domains with managed certificates, from Jet (Starter)Custom domains

Differences worth knowing before you switch

Section titled “Differences worth knowing before you switch”
  • Nothing is cached by default. GraphPilot stores a response only when your origin’s Cache-Control or your schema’s @cacheControl allows it. A service that says neither passes everything through.
  • Only Cache-Control is read. Surrogate-Control and Expires are ignored, so a lifetime your current CDN takes from either one has to move into Cache-Control.
  • Choose who shares an entry deliberately. Data that is the same for a whole customer belongs in a named scope or a vary rule, not in a per-user entry that misses for every member. On a GraphQL API, @cacheControl(scope:) defaults to PUBLIC, as in Apollo Server. See who shares an entry.
  • A response that sets a cookie is never stored. If your origin touches the session on every request, fix that first. See when a response is cached.
  • Writes purge what they name. A GraphQL mutation purges what it returns, so one that returns Boolean! purges nothing; see automatic invalidation. A plain HTTP write purges the keys its response names in Surrogate-Key; see the Surrogate-Key header.
  • GraphQL query text is hashed verbatim, and the cache is per edge location. Hit rates depend on how consistently your clients send the same requests and how concentrated your traffic is. See edge locations.
  • Configuration lives in files you deploy. gpilot.toml, and your schema for a GraphQL API, go up together with gpilot deploy, so they can live in version control and ship from CI. Keep a JWT provider’s shared HMAC secret out of version control, or use an asymmetric provider.
  1. Translate your rules. Move your cache rules into your origin’s Cache-Control (or, for a GraphQL API, into @cacheControl in your exported schema), and write the partitioning and authentication settings into gpilot.toml.
  2. Create the service and deploy. The GraphQL quickstart and the HTTP quickstart cover it. Read the findings the build reports, in the gpilot deploy output or in the portal under schema and config findings.
  3. Send a share of real traffic to the service hostname. Replay production requests, or point one client or one environment at https://<subdomain>.<label>.graphpilot.cloud.
  4. Compare hit rates. Read gp-cache on the responses, or use Insights (part of every plan). A PASS names its reason in gp-cache-reason; see troubleshooting.
  5. Check that writes clear what they should. Run your usual writes and repeat the requests they affect. Replace the purge calls your backend makes today with the purge API; the API key it uses needs the cache:purge permission.
  6. Verify the signature at your origin, and add the GraphPilot edge IP ranges to your firewall if you restrict who may connect. See request signing. Start rejecting unsigned requests only once all traffic reaches your origin through GraphPilot, or your current CDN’s requests fail.
  7. Cut over. Change your clients’ endpoint to the service hostname, or point your own hostname at GraphPilot with a custom domain (from Jet (Starter)). Keep the old path available until the new one has served real traffic for a while.
  8. Work through the go-live checklist.