
GraphQL performance on a Hyva storefront comes down to four levers: send cacheable queries as GET so Varnish and full page cache can store them, enable Magento’s resolver cache, use persisted queries to shrink request size, and cap query depth and complexity. Hyva fetches data client-side with Alpine.js and the browser Fetch API, so every uncached GraphQL call is a live round trip to your Magento backend, and those add up fast.
Hyva made your storefront fast by removing the heavy Luma JavaScript. But Hyva is also more GraphQL-driven than Luma, because interactive pieces like the cart, mini-cart, and customer sections fetch their data over GraphQL at runtime. If those calls are slow or uncacheable, you trade rendering speed for network latency. This guide covers how to keep the GraphQL layer as fast as the theme.
How Hyva uses GraphQL, and why it matters
On a Luma store, most data is rendered server-side and hydrated with jQuery and Knockout. Hyva takes a different path. It renders the page server-side too, but interactive and customer-specific data, cart contents, wishlist, customer sections, is fetched client-side by posting GraphQL queries to Magento’s /graphql endpoint using Alpine.js and the Fetch API. For heavier state some teams add Apollo Client, but the default is intentionally light.
This design keeps the initial page fast and cacheable, because the customer-specific parts load after the shell. The tradeoff is that those GraphQL calls happen on real user devices over real networks. A query that takes 400 milliseconds on your dev machine can take much longer on a mobile connection, and if it blocks an interaction, the shopper feels it. The whole game is making those calls fast, few, and cacheable.
Lever one: make queries cacheable with GET
The single biggest GraphQL performance decision in Magento is GET versus POST. Magento can cache GraphQL query responses in Varnish and full page cache, but only for GET requests marked as cacheable. POST requests are never cached.
So any query that returns non-personalized data, product data, category data, CMS content, should be sent as a GET request with the proper cache headers, so Varnish serves it without touching PHP. Mutations and personalized queries, cart, customer, checkout, must be POST and stay uncached because they are unique per session. Getting this split right means your catalog GraphQL traffic is served from cache while only genuinely dynamic calls reach the application.
| Query type | Method | Cacheable | Example |
|---|---|---|---|
| Product and category data | GET | Yes, via Varnish and FPC | products, categoryList |
| CMS content | GET | Yes | cmsPage, cmsBlocks |
| Cart and checkout | POST | No, session-specific | cart, setShippingAddress |
| Customer data | POST | No, per customer | customer, customerOrders |
| Mutations | POST | No | addProductsToCart |
Lever two: turn on resolver caching
Magento’s GraphQL layer supports resolver-level caching, which stores the resolved output of individual resolvers so repeated resolution of the same data does not re-run the work. This matters for queries that hit the same product or category repeatedly across many shoppers. Enable and tune the resolver cache, and confirm it is actually being hit in your environment, because a misconfigured cache silently falls back to full resolution and you lose the benefit without any error.
Resolver caching pairs with Varnish rather than replacing it. Varnish serves whole cacheable responses from the edge; resolver caching speeds up the responses that do reach PHP. Together they cover both the cached and the application paths. This is the same layered thinking behind any serious Magento development performance effort: cache at every level where the data allows it.
Lever three: persisted queries to shrink requests
Persisted queries replace a long GraphQL query string with a short hash. Instead of sending the full query text on every request, the client sends a hash that maps to a pre-registered query. This reduces request size significantly, by a large margin on complex queries, which matters most on mobile networks where upload bandwidth is limited and every byte of request adds latency.
For a Hyva storefront serving a lot of mobile traffic, persisted queries cut the overhead of the client-side GraphQL calls that power interactivity. They also make it harder for third parties to send arbitrary expensive queries against your endpoint, because only registered queries are accepted. The tradeoff is a registration step in your build, which is a reasonable price for the size and security gains.
Lever four: query discipline and complexity limits
The most common GraphQL performance mistake is asking for too much. Because GraphQL lets a client request any shape of data, it is easy to write deeply nested queries that pull far more than a component needs. Deep nesting multiplies resolver work and database queries.
Two disciplines fix this:
- Request only the fields a block needs. The core advantage of GraphQL is smaller payloads and fewer round trips. Ask for exactly what renders, nothing more. A mini-cart does not need the full product description.
- Enforce query depth and complexity limits. Set maximum query depth and complexity on the endpoint so no single query, whether from your own frontend or an abusive client, can overload the backend. This is both a performance and a security control.
Batching related data needs into one query also helps: combining several small data requirements into a single GraphQL call reduces round trips, as long as you do not over-nest in the process. The balance is fewer requests without heavier individual queries. When you connect a Hyva frontend to external systems, this discipline matters even more, as covered in wiring a Hyva frontend to enterprise systems with GraphQL.
A practical tuning checklist
Work through these in order on an existing store:
- Audit GET versus POST. Confirm every non-personalized query is a cacheable GET and every personalized query is a POST. Fix any cacheable query stuck on POST.
- Verify Varnish is caching GraphQL. Check that cacheable GraphQL GET responses are actually served from Varnish, not falling through to PHP.
- Enable and confirm resolver caching. Turn it on and verify hits in your environment.
- Profile your heaviest queries. Find the slowest client-side calls with browser dev tools and reduce their field selection and nesting.
- Add persisted queries if you serve significant mobile traffic or want endpoint hardening.
- Set depth and complexity limits to protect the backend.
Each step is measurable. Profile before and after so you know the change helped rather than assuming it did.
GraphQL and Core Web Vitals on Hyva
The GraphQL layer connects directly to the metrics you migrated to Hyva to improve. Client-side GraphQL calls run on the main thread when the browser processes their responses, and heavy processing there can hurt Interaction to Next Paint, the responsiveness metric that replaced First Input Delay as a Core Web Vital.
A shopper who taps add-to-cart triggers a GraphQL mutation, and the browser must process the response and update the UI. If that work is heavy, the tap feels laggy. Keeping mutation responses small, deferring non-critical GraphQL calls until after the interaction, and avoiding large client-side data processing all protect INP. The same logic applies to layout: if a GraphQL call populates a region without reserved space, its late arrival shifts the page and damages Cumulative Layout Shift. Reserve space for anything GraphQL fills after load.
This is why GraphQL tuning is not a backend-only concern. On Hyva, the network and the frontend are the same performance story, and a slow query surfaces as a poor Core Web Vitals score, not just a slow API.
Monitoring GraphQL in production
Dev-machine timings lie, because they do not reflect real networks or real cache-hit rates. Monitor the GraphQL layer in production instead. Watch the cache-hit ratio on your cacheable GET queries, because a ratio that drops after a deploy usually means a query slipped back to POST or lost its cache headers. Track the response-time distribution of your key queries at the 75th percentile, the same threshold Core Web Vitals uses, so you see what typical shoppers experience rather than an average smoothed by fast connections.
Set an alert on your slowest customer-facing queries so a regression surfaces before shoppers complain. Server-timing headers and real-user monitoring both help here. The goal is to catch a GraphQL slowdown as a trend in the data, not as a support ticket, because by the time shoppers report it you have already lost conversions. Treat the GraphQL layer as a monitored production system, not a thing you tune once at launch and forget.
Frequently asked questions
Why are my Hyva GraphQL calls slow?
Usually because cacheable queries are being sent as POST and never cached, or because the queries request deeply nested data. Move non-personalized queries to cacheable GET so Varnish serves them, and trim the fields each query requests to only what the component renders.
Can Magento cache GraphQL responses?
Yes, for GET requests marked cacheable, via Varnish and full page cache, plus resolver-level caching for the application path. POST requests, including all mutations and personalized queries, are never cached because they are session-specific.
What are persisted queries and do I need them?
Persisted queries send a short hash instead of the full query string, cutting request size and hardening the endpoint against arbitrary queries. They help most on mobile-heavy stores. They add a registration step to your build, which is a fair tradeoff for the gains.
Does Hyva use Apollo Client?
Not by default. Hyva fetches GraphQL data with Alpine.js and the browser Fetch API to keep the frontend light. Some teams add Apollo Client for heavier client-side state, but it is optional, not part of the standard Hyva approach.
How do I stop expensive GraphQL queries from overloading my store?
Set maximum query depth and complexity limits on the GraphQL endpoint, and use persisted queries so only registered queries are accepted. Together these prevent any single query from consuming disproportionate backend resources.
Where this fits
GraphQL performance on Hyva is not one setting, it is four levers working together: cacheable GET queries served by Varnish, resolver caching on the application path, persisted queries to shrink and harden requests, and query discipline to keep each call lean. Tune them in order, measure each change, and the GraphQL layer stays as fast as the theme.
Bemeir is the first US-based Hyva partner and a full Adobe Commerce agency with a deep technology partner ecosystem across hosting, caching, and API tooling. We build and tune high-performance Hyva storefronts, and we also work across Shopify, Shopware, and BigCommerce. Read more about Bemeir and how we approach storefront performance.
External references: a practical guide to implementing GraphQL in Hyva, a deep dive on GraphQL resolver caching and query limits, and a broader Magento 2 GraphQL guide for 2.4.8.





