How is the requested cost of a GraphQL Connection calculated?

According to Shopify’s GraphQL Admin API documentation, the requested cost of a connection is based on its first or last argument.

However, the cost calculation appears to have changed recently.

For example, suppose the cost of the object is 3, and the connection itself has a fixed cost of 2. Based on the previous calculation, we would expect the requested cost to be:

Requested Cost = 2 + first × 3

However, Shopify now returns the following requested costs:

first requestedQueryCost
1 5
2 5
3 8
4 8
5 11
6 11
7 11
8 14
13 17
21 20
34 23
55 26
91 29
149 32
245 35

The requested cost no longer appears to increase linearly with the first parameter. I’d like to understand how the connection cost is calculated now.

  • Has Shopify changed the connection cost calculation algorithm?
  • Is there any documentation describing the current algorithm?
  • If the algorithm is intentionally not public, is there a recommended way to conservatively estimate the requested cost of a connection before sending the query?

Because our query is dynamic generated by the different scenarios, we need an estimation method that is reasonably close to Shopify’s requestedQueryCost and does not underestimate it. This allows us to determine an appropriate page size before sending the GraphQL request.

The part that trips most people up is that the multiplier isn’t the object’s intrinsic cost, it’s the cost of the fields you actually select on the node. Scalars are 0, a nested object is 1, a nested connection is 2 plus its own children. So a flat “object = 3” assumption usually doesn’t hold, since the per-node number moves with your selection set.

That’s also why the numbers you’re seeing don’t line up with 2 + first x 3. It’s hard to derive from the outside without the exact query. Can you paste the selection set inside the connection plus the full extensions.cost block from the response? With that you can trace it field by field and see where the 3 is actually coming from.

lumine makes a fair point that the per node cost is really the sum of the fields you select, not one flat number. Here the selection set is fixed on every row though, so the only thing moving is first, which is what makes the pattern show up.

I dropped your 15 rows into a sheet and they all fit this:

requestedQueryCost = 2 + 3 * E

where 2 is the connection cost, 3 is your fixed node cost, and E goes up by one each time first crosses the next Fibonacci number (3, 5, 8, 13, 21, 34, 55, 89, 144, 233). So 1 to 2 is E1, 3 to 4 is E2, 5 to 7 is E3, and it keeps going the same way up to your 245 to 35 row. In other words the cost is logarithmic in first now, not linear, so the old 2 + first * 3 is gone.

Small helper I used to estimate before sending. It never came back lower than the real number on any of your rows:

function connectionMultiplier(first) {
      let a = 3, b = 5, e = 1;
      while (a <= first) { e++; [a, b] = [b, a + b]; }
      return e;
    }
    function estimateRequestedCost(first, connectionCost = 2, nodeCost = 3) {
      return connectionCost + nodeCost * connectionMultiplier(first);
    }
    // estimateRequestedCost(245) is 35

Two caveats. This is just me reverse engineering your numbers, the public docs still show the old linear model, so treat it as an observed pattern Shopify could change rather than a contract. And the nice side effect is that big pages are almost free now, first: 250 costs about the same as first: 55, so you can request large pages and stop sweating the multiplier. For a hard guarantee still read requestedQueryCost and throttleStatus.currentlyAvailable off the response and back off from there.

If you hit a query where the estimate drifts, especially nested connections since those stack, happy to look.

@HamidEjaz, Thanks for your explanation. The object cost isn’t a fixed value—I was only using 3 as an example to illustrate the calculation. I did some additional testing on my side and found results very similar to yours. I hope someone from Shopify can provide more details about the new connection cost calculation, even if they don’t plan to publish an official specification. Any additional guidance would be very helpful for developers who need to estimate the requested cost before sending a query.

@Simon_Liang got it, thanks for clarifying the 3 was just illustrative. Good to hear your own testing lined up with the pattern too. Since none of this is official, a small safety margin on the estimate is worth keeping so a schema change can never make you underestimate. Agreed that some official detail from Shopify would be really helpful for partners here.