Shopify GraphQL Admin API: Production Rate Limit Strategy (2026)
No7 Engineering Team
Growth Architecture Unit

The Shopify Admin GraphQL API does not rate-limit by request count; it limits by calculated query cost. Treat it like a REST endpoint, fire concurrent paginated requests, and you hit a wall of 429s. Managing this API in production requires extracting the throttle status from every response, queueing mutations based on point availability, and knowing exactly when to abandon synchronous queries for the Bulk Operations API. Figures below were re-verified against the Shopify API limits documentation in September 2026, against the 2026-07 stable API version.
How calculated query cost replaces REST rate limits
In the legacy REST API, rate limits were straightforward: a standard store allowed two requests per second, with a burst bucket of 40. The GraphQL Admin API discards request counting entirely in favour of a complexity-based model. Every requested field, connection, and pagination argument carries a point value.
A simple query fetching a product ID and title costs 1 point. A query fetching a product, its first 50 variants, and the first 10 metafields for each variant costs far more. Shopify calculates this cost before execution. If the requested query cost exceeds your available bucket, the request is rejected immediately. There is also a hard ceiling that no plan lifts: a single query may not exceed 1,000 points, enforced on the requested cost before execution. When execution finishes, the bucket is refunded the difference between requested and actual cost, which is why under-fetched connections are cheaper than their requested cost suggests.
So the trade is network overhead against point consumption. While GraphQL allows you to fetch a product, its inventory, and its metafields in a single HTTP request, doing so aggressively across a large catalogue will rapidly drain your API capacity. Most teams over-fetch in their first GraphQL migration and end up with integrations that fall over during a peak sync.
Extracting throttleStatus for production retry logic
You cannot blindly retry a throttled GraphQL request using a standard exponential backoff. Because the API tells you exactly how much capacity you have left and how fast it regenerates, your retry logic should be deterministic.
Every successful and throttled response from the Shopify Admin GraphQL API includes an extensions.cost.throttleStatus object. This object contains three critical integers: maximumAvailable, currentlyAvailable, and restoreRate.
Production integrations must parse this object on every network call. If currentlyAvailable drops below a safe threshold, usually around 200 points on a Standard plan, your application should pause the queue. The pause duration is not a guess; it is calculated by dividing the deficit by the restoreRate.
This fails when you have multiple independent workers querying the same store. The throttleStatus represents the global state of the store's API bucket, not the state of your specific app. If a third-party inventory app is aggressively consuming points, your currentlyAvailable value will drop unexpectedly between requests. Once you have more than a couple of workers, one place has to own the budget, usually a Redis-backed coordinator, or they trample each other.
Shopify Plus vs Standard GraphQL rate limits in 2026
The ceiling for query execution depends directly on the merchant's subscription tier, and the numbers moved when Shopify doubled Admin API limits in late 2024. Per the current limits table (verified September 2026), restore rates are 100 points per second on Standard, 200 on Advanced, 1,000 on Shopify Plus, and 2,000 on Shopify for enterprise (Commerce Components). Bucket capacity scales with the restore rate; read the exact figure from throttleStatus.maximumAvailable rather than hardcoding it, because it is 2,000 points on Standard and 20,000 on Plus today and Shopify has changed it before.
The practical difference is throughput, not query size. A Plus store refills in a fraction of the time, which is what makes deep pagination across B2B company locations or heavy metafield architectures viable. But the 1,000-point single-query ceiling applies identically on every plan, so a query shaped for Plus is not "bigger", it is simply retried less often.
That also removes the portability trap engineers assume exists. A public app cannot execute a 1,500-point query anywhere, Plus or not, so the correct design is the same for every tier: cap each query well under 1,000 points, paginate, and let the restore rate decide how fast the queue drains. What does change across tiers is the safe pause threshold in your queue, which should be a proportion of maximumAvailable, not a fixed 200 points.
When to abandon throttled queries for the Bulk Operations API
The most common mistake we see in Shopify GraphQL implementations is attempting to sync an entire product catalogue using standard paginated queries. Even with perfect throttleStatus management, fetching 50,000 products will take hours and constantly block other API consumers.
When you need to extract large datasets, you must switch to the Bulk Operations API. This API allows you to submit a single GraphQL query that Shopify executes asynchronously. The results are written to a JSONL file, and Shopify provides a secure URL to download the file once the operation completes.
The primary advantage is that Bulk Operations do not consume points from your standard API bucket beyond the trivial cost of creating, polling, and cancelling them. You can extract 100,000 orders without impacting the store's live integration capacity. Per the bulk query guide, the signed result URL expires one week after completion.
The catch: concurrency is versioned. On API versions before 2026-01, each app can run only one bulk operation of each type (one bulkOperationRunQuery and one bulkOperationRunMutation) at a time per shop, so a product export started by one service blocks an order export from another until it finishes. From 2026-01 onwards, per the concurrency notes, each app can run up to five bulk queries and five bulk mutations concurrently per shop, tracked by ID with bulkOperation(id:); the older currentBulkOperation query is deprecated. Either way, polling requires careful state management. If your worker dies while waiting for the webhook or polling the status, the JSONL file expires before you download it.
How to manage high-volume mutations in 4 steps
Mutations are inherently more expensive than queries. Every mutation carries a default cost of 10 points, and Shopify reserves the right to price individual fields higher. Updating inventory across 5,000 variants cannot happen in a single payload.
Shopify limits input arrays to 250 items for every API (queries and mutations return an error above that), but you will often hit the query cost limit before you hit the array limit. To manage high-volume mutations, you must batch your payloads based on the calculated cost, not just the array size.
- Calculate the mutation cost per item. Multiply the base cost by your batch size to ensure the total stays safely under 800 points.
- Monitor the restoreRate during execution. Track the regeneration speed to prevent throttling when consuming capacity at exactly the restore rate: 100 points per second on Standard, 1,000 on Plus.
- Implement a token bucket queue locally. Check your local Redis bucket before dispatching to sleep the worker instead of relying on a 429 error.
- Process the userErrors array. Iterate over the response array to catch validation failures that return a deceptive HTTP 200 status.
Testing query efficiency with the Shopify Dev MCP Server
Validating query cost during development has historically required executing the query against a live staging store and inspecting the response headers. This slows down the feedback loop and makes local testing difficult.
In 2026, the standard approach is to use the Shopify Dev MCP Server. This Model Context Protocol server exposes the Shopify Admin GraphQL schema directly to your local development environment and AI coding assistants. By introspecting the schema locally, you can validate query structures and identify expensive nested connections before they hit a real API bucket.
It earns its keep when you are designing complex queries that involve both standard Admin data and storefront-specific configurations. However, the MCP server does not simulate live API consumption. It will tell you if a query is syntactically valid, but it will not warn you if multiple concurrent queries will exhaust the 100 points/second Standard restore rate. You still need integration tests that mock the throttleStatus behaviour.
The migration cost: moving from REST endpoints
The REST Admin API has been a legacy API since 1 October 2024, and every new public app has had to be built exclusively on the GraphQL Admin API since 1 April 2025. Features like Product Bundles, complex B2B pricing, and advanced metafield definitions are exclusively available via GraphQL. Anyone still maintaining a legacy REST integration is past the point where migration is optional.
The migration cost is typically £15,000-£40,000 for a medium-complexity custom app, depending on how deeply the app relies on REST's call-counting limits. The engineering effort is rarely in rewriting the queries; it is in re-architecting the queueing system.
Take an app that updates prices on ERP triggers. Its legacy REST queue probably dispatches two requests per second (the old REST allowance was 2 requests per second with a 40-request burst on Standard). Migrating this requires replacing the simple rate limiter with a cost-aware batching engine. If you also use Shopify Functions to handle custom cart logic, you must ensure your Admin API mutations do not conflict with the data structures expected by your WebAssembly modules.
What to do next
Custom apps still on REST, or a GraphQL integration with no cost-aware retry, are fragile. Both fail on the same busy afternoon. The first step is to audit your existing network calls and log the requestedQueryCost and actualQueryCost for every request.
Identify the queries that routinely consume more than 500 points. These are your bottlenecks. Refactor them to use shallower pagination, or move them entirely to the Bulk Operations API if they are not serving real-time user requests. Standard-plan stores that keep draining the 2,000-point bucket at 100 points per second should ask whether the cost of optimising the queries outweighs the cost of upgrading to Shopify Plus for the 20,000-point bucket and 1,000 points per second restore rate. Weeks of re-architecting a boxed-in app usually cost more than the upgrade.
Our verdict
If you run more than a handful of mutations per request on Shopify Plus, treat the calculated query cost as a hard architectural constraint, not a tuning pass bolted on at the end. At No7 Software we default to bulk operations over chained throttled mutations on every Plus build above roughly £2M GMV. It is the one change that most reliably keeps the Admin API under its rate ceiling. The teams we audit that hit 429s in production almost always optimised the query shape last instead of first; if you are choosing between re-architecting a constrained app and moving to the 20,000-point Plus bucket, price both before you commit to either.
Newer related guide: Shopify Customer Accounts API: Passwordless in Production (2026).
Frequently Asked Questions
The questions buyers and engineers ask us most about this topic.
How much does it cost to migrate from Shopify REST to GraphQL in 2026?
Migrating a legacy custom app from REST to GraphQL typically costs between £15,000 and £40,000, depending on complexity. The primary engineering expense is not rewriting the queries, but re-architecting your queueing system to handle calculated query costs instead of simple request counting.
What is the difference between standard and Shopify Plus GraphQL rate limits?
As of September 2026 the Admin GraphQL API restores 100 points per second on Standard, 200 on Advanced, 1,000 on Shopify Plus, and 2,000 on Shopify for enterprise, with bucket capacity scaling to match (2,000 points on Standard, 20,000 on Plus). A single query is capped at 1,000 points on every plan, so Plus buys throughput for deep pagination, not larger queries.
When does the Bulk Operations API make sense vs standard queries?
The Bulk Operations API is required when extracting large datasets (over 1,000 records) or deeply nested connections that would exhaust your standard point bucket. It processes asynchronously and outputs a JSONL file that expires after one week, and it does not draw on your live application's GraphQL point bucket. From API version 2026-01 an app can run up to five bulk queries and five bulk mutations per shop at once.