← All writing
Platform & APIs

Shopify Admin GraphQL rate limits, explained: cost, buckets and what to do about them

Keith Pillay · 27 September 2026 · 3 min read

If you're building anything that reads a lot of data from a Shopify store, you need a mental model of how the Admin GraphQL API limits you. REST gave you a simple "calls per second". GraphQL is different, and the difference shapes your design.

Numbers below come from Shopify's documentation as I read it while building an app. Limits change, so check the current docs before relying on any of them.

Cost, not call count

Every GraphQL field has a cost, and a query's cost is the sum. Roughly:

  • Scalars and enums cost 0.
  • Objects cost 1.
  • Connections are priced by how many items you ask for (first: 50 costs more than first: 5), including nested connections.
  • Mutations carry a higher base cost.

The response tells you what you used, in an extensions block with the requested cost, the actual cost and the throttle status. Read it in development. It's the fastest way to learn what a query really costs.

The leaky bucket

You don't get a fixed number of calls per second. You get a bucket of points that refills at a steady rate:

  • Each query removes its cost from the bucket.
  • The bucket refills continuously.
  • If a query would overdraw the bucket, it's throttled.

The restore rate depends on the shop's plan: Standard is 100 points per second, with higher rates on larger plans. The exact bucket size isn't something to hard-code, because the throttle status in each response reports the maximum available at runtime.

The per-query cap

Independently of the bucket, a single query has a maximum cost of 1,000 points. Exceed it and the query is rejected outright, with a MAX_COST_EXCEEDED error, no matter how full your bucket is.

This catches people who nest connections: products, each with media, each page asking for large first values. The requested cost multiplies. A page of 50 products with 20 media each is already over the cap. The fix is smaller pages, such as 25 to 40 products with 10 to 20 media, and a follow-up query for the occasional product with more.

Why paging stops scaling

Do the arithmetic for a catalogue of 10,000 products with several images each. You're looking at hundreds of paged requests and, in the worst case, more than an hour of throttled waiting on a Standard plan. At 100,000 products it isn't practical at all.

What to do about it

Use bulk operations for big reads. You submit one query, Shopify runs it asynchronously, and you download a JSONL file. The mutation that starts it is the only part that counts as a normal request; the export itself isn't subject to the rate limit. I covered this in Shopify bulk operations: scanning a whole catalogue.

Use paginated queries for small, targeted reads. Re-checking one product after a webhook is cheap: roughly 1 point plus a little per connection.

Batch with nodes. If you have a list of IDs, fetch them in one call with the nodes query instead of one call per ID. It preserves input order and returns null for missing items.

Back off properly. On a throttle, wait for the bucket to refill based on the throttle status, not a guess, then retry. Add jitter if several workers share a shop.

Keep queries lean. Ask only for the fields you use. Every extra nested connection costs points.

A decision rule

| Situation | Tool | |---|---| | Whole catalogue, or thousands of objects | Bulk operation | | A handful of known IDs | nodes query | | One object, reacting to a webhook | Single targeted query | | Writing many records | Bulk mutation, or batched mutations with backoff |

One caveat from my own testing

A bulk mutation used to create thousands of test products did not fire the individual create webhooks that single creations do. If your design depends on webhooks to notice changes, know which creation paths trigger them, and keep a full re-scan as the ground truth.

The short version: estimate cost before you write the loop, and reach for bulk operations earlier than you think you need to.

Hiring a senior Shopify developer?

I'm open to remote roles worldwide. Send a message and I'll reply within a day.