I’ve encountered a behavior I wasn’t expecting today :
No matter how many “NOT ID” clauses I hit the API with, the query cost did not flinch a bit.
I actually hit the editor limit (trying to paste 1000 IDs) :
My questions are :
- is this normal, expected behavior on Shopify’s side, or is the cost of such kind of query susceptible to change in future API versions ?
- if there’s no cost limit, I’m then concerned about a total size of the request, or any kind of limit that would make transmitting thousands of IDs this way a problem, can we have any info on that ?
Context : we have to fetch the fulfilled orders created in the last 30 days. Once processed on our end, we store the IDs not to process them ever again. So now either we fetch all the orders of the last 30 days and filter them server-side (which sucks, loads of data transferred for nothing), or we let Shopify do the filtering for us, like on the screenshots.
Using webhooks would be very nice instead, but this might not be possible for our implementation at the moment.
Hi @Alex-OddBrew! The flat cost you’re seeing is expected, and it won’t change with how many NOT id: clauses you add. Calculated query cost is based purely on the fields you select, not on the contents or length of the query: filter. A scalar or enum is 0, an object is 1, and a connection is sized by your first/last argument, so orders(first: 1) { nodes { id name } } lands at cost 3 no matter how complex the filter string gets. The full breakdown is in the rate limits doc.
On size limits, input arguments that accept an array max out at 250 items, but that applies to array inputs like nodes(ids: [...]), not the orders query: string, which is just a single String. There’s no published hard limit on the raw filter string length.
That said, chaining thousands of NOT id: terms isn’t really a scalable pattern for request size or search cost. Since you’re already tracking processed IDs locally, I’d filter on created_at:>=<30 days ago> fulfillment_status:fulfilled, sort by created_at, and page through with cursors, then dedupe against your stored IDs client-side (search syntax reference). For larger historical pulls, bulk operations avoid per-query cost entirely, and longer term the orders/fulfilled webhook is the cleanest way to process each order exactly once if that ever becomes feasible on your side.
I hope this helps!