Shopify GraphQL Query Cost: Production Throttling Patterns (2026)
No7 Engineering Team
Growth Architecture Unit

The Shopify Admin GraphQL API does not enforce rate limits by request count; it throttles traffic using a calculated query cost model based on requested fields. Managing this API in production requires extracting the throttleStatus from every response, queueing mutations based on point availability, and transitioning large data syncs to the Bulk Operations API to avoid 429 errors.
How Shopify calculates GraphQL query cost vs REST rate limits
Unlike the legacy REST Admin API, which uses a leaky bucket based purely on request volume, the shopify graphql endpoint measures the computational expense of retrieving your requested data. Every field in the schema carries a point value. Scalar fields (like id or title) cost 1 point, while complex connections or heavily nested objects multiply the cost based on the first or last pagination arguments.
If you treat the GraphQL endpoint like REST and fire concurrent paginated requests, your application will quickly hit a wall. A single request asking for 250 orders with fully expanded line items, customer details, and metafields can consume hundreds of points instantly. Production integrations must shift from counting HTTP requests to tracking point consumption on every network call.
The API calculates a requestedQueryCost before execution. If this estimated cost is higher than your current bucket capacity, the request is rejected before any data is fetched. If it passes, the API executes the query and returns an actualQueryCost, which is often lower than the estimate if the returned arrays are smaller than the maximum requested pagination bounds.
Shopify Plus vs Standard GraphQL rate limits in 2026
The ceiling for query execution depends directly on the merchant's subscription tier. For standard Shopify plans, the Admin GraphQL API bucket holds a maximum of 1,000 points and restores at 50 points per second. This means the absolute maximum cost of a single query cannot exceed 1,000 points, regardless of how long your worker thread waits.
Merchants paying for Shopify Plus — typically around £1,800-around £2,500/month depending on GMV — receive double the API capacity. The Plus bucket holds 2,000 points and restores at 100 points per second. This higher ceiling allows for deeper pagination and more complex nested connections, which is critical when dealing with B2B company locations or extensive metafield architectures.
However, relying on the Plus limit creates a portability risk. If you build a custom app that routinely executes 1,500-point queries, it will instantly fail with a structural error if installed on a standard store. If you are building public apps or integrations that span multiple merchant tiers, you must cap your maximum query cost at 1,000 points to ensure universal compatibility.
Extracting throttleStatus for deterministic retry queues
You cannot blindly retry a throttled GraphQL request using a standard exponential backoff library. Because the API tells you exactly how much capacity you have left and how fast it regenerates, your retry logic should be deterministic. Exponential backoff wastes time; deterministic sleeping optimises throughput.
Every successful and throttled response from the Shopify Admin GraphQL API includes an extensions.cost object. This object contains three critical integers inside the throttleStatus block: maximumAvailable, currentlyAvailable, and restoreRate.
Deterministic Queue Rules
- Parse every response — Extract
currentlyAvailablefrom the extensions block on every network call, not just failures. - Set a safety threshold — Pause your worker queue when points drop below 200, rather than waiting for a 429 error to occur.
- Calculate exact sleep time — Divide your point deficit by the
restoreRate. If you need 400 points and have 100, sleep for exactly(400 - 100) / 50 = 6 seconds.
By implementing a token bucket queue on your application side that mirrors Shopify's internal state, you prevent the cascading 429 errors that plague naive API clients. We have found this pattern dramatically improves the reliability of heavy background jobs.
Handling MAX_COST_EXCEEDED and 429 errors in production
There are two distinct failure modes when you breach the Shopify GraphQL query cost limits, and they require completely different handling strategies.
The first is a hard MAX_COST_EXCEEDED error. This occurs when the requestedQueryCost of your operation exceeds the maximumAvailable capacity of the bucket itself. If you encounter a MAX_COST_EXCEEDED error, the API response will clearly state the maximum cost allowed and the cost you attempted to request. This is a structural failure. Retrying will never work; the query is fundamentally too large for the merchant's plan. You must rewrite the query to request fewer nodes, drop nested connections, or reduce the first: 250 argument to first: 50.
The second failure mode is a standard HTTP 429 Too Many Requests response, often accompanied by a Throttled message in the errors array. This happens when your query is structurally valid, but the currentlyAvailable points in the leaky bucket have been temporarily exhausted by concurrent requests. In our experience, we typically see this when a merchant triggers a mass inventory sync or when a poorly configured webhook handler attempts to resolve too many payload references simultaneously. This is a temporal failure, and your deterministic retry queue should handle it smoothly.
How to migrate a REST polling loop to GraphQL in 4 steps
For agencies migrating legacy infrastructure, translating a REST-based synchronisation job to GraphQL requires rethinking the pagination strategy. You cannot simply swap endpoints; you must redesign the loop.
- Audit the legacy REST payload fields. Map every REST property to its GraphQL equivalent using the Shopify.dev schema explorer. You will often find that REST returned 50 fields when your application only needed 4. Drop the unused fields to lower the query cost.
- Calculate the worst-case query cost. Multiply the requested fields by the pagination limit. Ensure the total
requestedQueryCoststays safely below the 1,000-point standard limit. - Implement cursor-based pagination. Replace the REST
pageparameter with the GraphQLaftercursor. ExtractpageInfo.hasNextPageandpageInfo.endCursorfrom the response to drive the loop. - Inject the deterministic sleep function. Read the
extensions.cost.currentlyAvailablevalue at the end of each iteration and block the thread if points fall below your safety threshold.
When executed correctly, this pattern allows you to sync thousands of records without ever triggering a rate limit violation.
When to abandon synchronous queries for the Bulk Operations API
If your application needs to export 50,000 products or ingest a massive catalogue update, synchronous GraphQL pagination is the wrong architectural choice. Paginating through large datasets consumes excessive API capacity, blocks other background jobs, and exposes your integration to network timeouts.
Instead, use the Shopify Admin Bulk Operations API. By submitting a bulkOperationRunQuery mutation, Shopify executes the query asynchronously on their infrastructure and provides a signed URL to download the results as a JSONL file. This bypasses the standard query cost limits entirely, allowing you to extract massive datasets for a flat, minimal point cost.
The trade-off is latency. A bulk operation can take anywhere from a few minutes to several hours depending on platform load and dataset size. It is strictly for background jobs, not real-time user interfaces. For real-time flows, such as those relying on the Shopify MCP Server for agentic commerce, you must rely on targeted synchronous queries with strict pagination limits.
Integrating GraphQL operations with Shopify Functions
When building backend extensions, you often need to fetch additional context before executing custom logic. However, Shopify Functions in production operate under strict constraints — they are capped at 11 million WebAssembly instructions per invocation and must execute within a rigid sub-5ms window.
Because Functions execute synchronously during the checkout flow, they cannot make external HTTP calls to the Admin GraphQL API to fetch missing data. If your Function requires complex merchant data (like custom volume pricing tiers or specific B2B company logic), you must pre-calculate that data via the Admin GraphQL API in a background worker. You then store the results in Metaobjects, which the Function can read natively during execution without incurring additional network latency or query cost.
What to do next: auditing your API usage
Blindly throwing queries at the Shopify Admin GraphQL API will eventually result in throttled traffic, degraded sync performance, and failed background jobs. The first step to stabilising your integration is visibility.
Start by wrapping your GraphQL client to log the extensions.cost.actualQueryCost of every operation. Identify the top five most expensive queries in your codebase. Often, you will find a nested connection that requests 100 nodes when the business logic only requires the first 3. By aggressively trimming first arguments and dropping unused fields, we usually see a 40-60% reduction in query cost.
You must also review your webhook handlers. A common anti-pattern is firing a synchronous GraphQL query immediately upon receiving an orders/create webhook. During a flash sale, this will instantly drain your bucket. Instead, push webhook payloads to an internal queue and process them sequentially using the deterministic token bucket logic described above. This decouples incoming event volume from your API consumption rate.
If you are building multi-tenant apps or handling enterprise data volumes, implement a deterministic queue based on the currentlyAvailable points rather than relying on generic HTTP retry libraries. Stop treating the GraphQL endpoint like a REST API, and start managing it like a computational budget.
Frequently Asked Questions
The questions buyers and engineers ask us most about this topic.
How much does the Shopify Admin GraphQL API cost to use?
The API is included in your base Shopify subscription. However, its usage is rate-limited by a calculated query cost. Standard plans (typically £25-£300/month) receive a 1,000-point bucket, while Shopify Plus plans (typically around £1,800-£2,500/month) receive a 2,000-point bucket. There are no per-request billing charges.
What is the difference between standard and Shopify Plus GraphQL rate limits?
Standard Shopify plans cap the Admin GraphQL API at a 1,000-point bucket that restores at 50 points per second. Shopify Plus doubles this capacity, providing a 2,000-point maximum bucket with a 100 points per second restore rate, allowing for significantly deeper pagination.
When does it make sense to use the Bulk Operations API instead of synchronous GraphQL?
If you are exporting or importing datasets larger than 1,000 records, synchronous GraphQL pagination will exhaust your API rate limits and risk network timeouts. The Bulk Operations API is the right choice for these large jobs, as it executes asynchronously and returns a JSONL file without draining your real-time query cost bucket.
Working on this? Send us the details — we'll take a look.