One URL
A CDN sees one blind endpoint
Every query and mutation shares one URL, with the operation and variables buried in the request. A CDN can't tell them apart, so read-heavy APIs hammer the origin all day.
Schema-driven GraphQL edge
Drop GraphPilot in front of your GraphQL API. Repeat queries answer from the edge, and every cache clears the moment your data changes.
Works with Apollo, Wundergraph, Hasura and any other GraphQL server. Free to start, no credit card required.
p95 cache-hit latency
Caching GraphQL is easy.
Put a normal CDN in front of GraphQL and three problems surface at once.
One URL
Every query and mutation shares one URL, with the operation and variables buried in the request. A CDN can't tell them apart, so read-heavy APIs hammer the origin all day.
Stale data
Short TTLs throw away the hit rate; long TTLs serve stale data. A clock can't say which mutation changed which result, so you either under-cache or risk correctness.
1 → N caches
A single write invalidates entities, lists and derived results across many cached responses. Hand-written purge rules are fragile and rarely stay correct.
There's already one.
We set out to cache a GraphQL API at the edge and kept hitting the same wall: caching was never the hard part, keeping it correct was. So we built the layer we wanted.
Where we go further
the schema you write
the query, keyed either way
The backend team owns it
Cache and invalidation are directives next to the fields they govern, so the team that owns a type owns how it caches. No central config to coordinate.
And can rely on it
Forget the id in a query and caching still holds: GraphPilot injects it, so every cached response stays invalidatable.
In front of any gateway, we cache a federated graph as one. First-class, not an afterthought.
An empty result is a real cache entry, cleared the moment a write could fill it.
Cache tags persist across invalidations, so nothing quietly goes stale.
No new gateway, no client changes. It sits in front of the API you already run.
See exactly which cache tags a mutation clears. Not a black box.
Built in Germany to EU standards. GDPR compliance by design, not a bolt-on.
One layer in front of your API.
GraphPilot is a GraphQL-native proxy, written in Rust. It sits in front of your API and caches it for you, reading your schema to decide what to cache, how long to hold it, and what to clear when your data changes.
Client
Web · Mobile · Server
Origin
GraphQL · REST · HTTP
Cache hits answer at the edge. Only misses and writes reach your origin.
Mutations invalidate
Change your data and GraphPilot refreshes every response that touched it, and shows you exactly which cache tags it cleared. When a mutation doesn't reveal everything it changed, the behaviours below close the gap, so nothing is left stale.
Cached responses
The mutation only invalidates the entries it touches; each refills on its next request, not from the mutation.
Changed elsewhere?
When a change happens somewhere GraphPilot can't see, an event on your bus, a cron job, an admin action in another system, call the purge API with the keys to clear. Full, precise control whenever you need it.
Purge from your event bus the moment upstream data changes, with no GraphQL mutation involved.
Expire a set of keys on a cron or a job when a batch import or recompute finishes.
An admin action in another service clears exactly the right cached reads.
Purge exact cache tags, or clear everything of a type by typename.
a change from your system
Your clients forget the id?
When a query skips a key field, most caches still store the response but can't clear it when the data changes. GraphPilot injects the keys your schema needs, so every response stays precisely invalidatable, one entity or a whole group.
The query your client sends
injected by GraphPilotOne product, keyed by its id and its SKU, so either one invalidates it.
A thousand requests,
When a spike sends the same query all at once, GraphPilot collapses them into a single origin request. The first one fetches; the rest wait and share its result, so nothing stampedes your origin. Your database feels one hit, not a thousand, and stays calm exactly when traffic doesn't.
One query.
Personalized responses stay cacheable. Radiogramm, a small expression language built into GraphPilot, reads straight from each request (a JWT claim, a header, a cookie) and derives a cache key from it. Write one line, and the same query splits into exactly the buckets your data varies on, with no leak between them.
Prefer to decide at the origin? Return a Vary response header and the same split happens server-side, no rule required.
jwt.sub ?? "public" // one bucket per signed-in userRadiogrammone query · separate buckets · no bucket sees another's data
Served from the
Repeat reads are answered close to your users on a global network, so felt speed holds up worldwide, not just next to your origin.
You could build this.
Storing a GraphQL response takes an afternoon. Keeping every cached read correct as data changes, and as your schema keeps evolving, is a distributed-systems problem you would maintain for the life of the product.
weeks to build, then permanent maintenance
drop it in front, keep shipping features
Stop choosing between
Put GraphPilot in front of your GraphQL API and get edge speed with invalidation you can actually trust.