Shopify GraphQL vs REST: The Rate Limit That Catches Teams

Shopify's REST Admin API is legacy and the GraphQL Admin API is the path Shopify documents for new development. The operational difference that catches teams is the rate limit: REST counts requests, GraphQL counts calculated cost, so the same integration can run comfortably or throttle constantly depending on how the queries are written.
Cost is charged per field and per connection node, not per call.
Two throttling models
REST uses a leaky bucket of about 40 requests that refills at roughly 2 per second. Every call costs one request regardless of how much data it returns, so an integration making many small calls burns the bucket fast even when each response is trivial.
GraphQL prices each query from 1 point for a simple object lookup to 30 or 50 points for orders with nested line items and customer data. Mutations typically cost about 10 points. Shopify returns the accounting on every response under extensions.cost, including the bucket state, so you can see the charge rather than infer it.
| Dimension | REST Admin API | GraphQL Admin API |
|---|---|---|
| Status | Legacy | Primary for new apps |
| Limit basis | Requests per second | Calculated query cost |
| Bucket | ~40 requests, refill ~2/sec | Points, restore rate scales by plan |
| Field selection | Full object returned | Request only what you need |
| Pagination | Page-based | Cursor-based |
| Bulk data | Not available | Bulk operations, async JSONL |
| Cost visibility | None | extensions.cost on every response |
According to Shopify's usage-limit reference, the restore rate scales with plan tier, from around 100 points per second on standard plans up to 1,000 on Plus, with a single-query ceiling that applies on every tier. Precisely because those numbers move, read them on shopify.dev rather than trusting a blog post, including this one.
The refund mechanism people miss
Shopify pre-charges the requested cost before execution and refunds the difference between requested and actual after. A query that could return 50 connections but finds 3 costs far less than its worst case. In 2026 the practical guidance is unchanged: measure the requested cost, not the returned payload.
That has a planning consequence: a query that is cheap in practice can still be rejected at submission if its worst-case cost exceeds what the bucket holds. Debugging the throttle by checking the actual data volume wastes an afternoon; the answer is in the requested cost.
Where points actually leak
Over-fetching. Requesting every field on a product query costs multiples of a five-field query. Teams that migrated from REST carry the habit of taking the whole object.
Deep nesting in one call. Variants, metafields, media and options in a single query look efficient and price accordingly. Two shallower queries are often cheaper than one wide one.
Large page sizes. first: 250 costs more than first: 50 even when the result set is sparse, because cost is assessed on the requested shape.
Retry storms. Retrying immediately on a throttle spends the refill you were waiting for. Back off with jitter and let the bucket recover.
Bulk operations change the arithmetic
We built a 10,000-product test catalogue and ran both methods against it, and the difference is not marginal.
For anything above a few hundred records, a bulk query is the correct tool. You submit a job, Shopify processes it server-side, and results arrive as a JSONL file on signed storage. The cost against the live bucket is effectively nil during processing, which is why a 10,000-product export that would take 200 paginated REST calls belongs in a bulk job.
The limitation is latency: bulk jobs are asynchronous, so they suit exports, migrations and nightly syncs rather than anything a merchant is waiting on in the admin.
Our verdict: budget in points, not calls. Instrument extensions.cost in staging, log the worst-case requested cost per query, and rewrite anything that needs more than a quarter of the ceiling. The realistic migration shape for an existing REST integration is endpoint by endpoint over 8 to 16 weeks, not a rewrite sprint, because the risk sits in the edge cases rather than the main path.
Two more limits worth knowing: GraphQL has no equivalent of some older REST conveniences, so a few workflows need restructuring rather than translation, and webhook payloads still arrive in their own shape regardless of which API you read with. If you are rebuilding a storefront rather than an integration, Hydrogen vs Liquid storefronts covers the front-end side of the same migration question.
extensions.cost.requestedQueryCost on the response.Ready to build a faster, higher-converting store?
Every Shoptimity theme ships with conversion widgets built in — so you get speed and features without stacking apps.
7-day free trial · all themes included · cancel anytime
Continue Reading

Shopify B2B Company Locations: Give Buyers the Right Access
Configure Shopify B2B company locations, verify buyer permissions and test pricing, addresses and pa...

Shopify Checkout Contact Settings: Separate Email From Shipping Phone
Configure Shopify checkout contact settings and test email, phone and shipping address requirements ...

Shopify POS Recent Carts: Share a Sale Without Reserving Stock
Learn how Shopify POS recent carts work across devices, what they do not reserve, and how to hand of...