Shopify GraphQL vs REST: which API to build on
REST still works. GraphQL is where new capability lands, and its rate limiting is the reason to move even when REST would do.
7 min read · APIs & data ·
Shopify has offered both a REST and a GraphQL Admin API for years. They're not equivalent any more: GraphQL is where new capability lands, and the rate-limiting model is meaningfully better for the kind of work integrations actually do.
Short version: build new work in GraphQL. Here's why, and what it costs to move.
The rate limiting difference
This is the substantive argument, not developer preference.
REST limits you by request count in a leaky bucket. Every request costs the same whether it returns one field or fifty, so a naive integration fetching one product at a time burns the bucket on requests that return almost nothing.
GraphQL limits you by calculated query cost. Cost scales with how much data you request, and every response tells you exactly where you stand:
``json "extensions": { "cost": { "requestedQueryCost": 102, "actualQueryCost": 46, "throttleStatus": { "currentlyAvailable": 1954, "restoreRate": 100 } }} ``
That does two useful things. You can fetch a product and its variants and its metafields in one request rather than three. And you can pace yourself precisely by reading the remaining budget, rather than firing requests until something throttles.
For an integration syncing a large catalogue, that's the difference between a job that completes and one that half-fails at midnight — the failure mode described in ERP integration.
The capability difference
Newer features appear in GraphQL first, and several exist only there. Bulk operations, which are how you should move a whole catalogue, are GraphQL-only. Some newer resources and fields have no REST equivalent at all.
If you build on REST today, you'll eventually need GraphQL for something, and you'll be maintaining two clients.
What's genuinely harder about GraphQL
Being fair about the trade-offs:
- The queries are more verbose. You must name every field you want.
- Errors are subtler. A mutation can return HTTP 200 with the operation having failed — you must select and check
userErrorson every mutation. Code that only checks the status code silently does nothing and reports success. This is the single most common bug in first Shopify integrations. - The cost model needs understanding before you can pace properly.
- Tooling is less familiar if your team has only done REST.
None of these are large. The userErrors one is a habit; the rest is an afternoon.
Pagination is the same idea in both
Neither has page numbers. Both use cursors:
``graphql products(first: 250, after: "eyJsYXN0X2lkIjo...") { edges { node { id title } } pageInfo { hasNextPage endCursor } } ``
Write the loop on the first query, not when it breaks. Code tested against a development store with twelve products passes and then fails in production — see the Admin API guide.
Migrating an existing integration
You don't have to do it all at once. A pragmatic order:
- Move the highest-volume calls first — usually product and inventory sync. That's where the cost model saves you most.
- Combine requests as you go. A REST integration making three calls per product usually becomes one GraphQL query.
- Move mutations, adding
userErrorshandling as you do. - Leave low-volume, working REST calls until you have a reason.
Pin the API version explicitly and diary the quarterly upgrade either way. That maintenance is a real ongoing cost and belongs in any app budget.
When REST is still fine
- An existing integration that works, isn't near rate limits, and doesn't need new features.
- A quick script against a small store.
- A library or platform you're using only supports REST.
There's no urgency to rewrite something that works. There's a strong argument not to start something new on it.
The reason to choose GraphQL isn't that it's newer. It's that one query replaces three requests, and the rate limiter charges you for data rather than for asking.
Is this the problem you’re looking at?
Send me the link to your store and a line about what is going wrong. You get a straight answer within one business day — no pitch, no obligation.
[email protected]Or see what I do around Shopify: services, work beyond the theme, selected work.