Query complexity calculations
Last updatedQuery complexity calculation#
The Integration API calculates query complexity to prevent system abuse. The score is based on the number and type of requested fields and their associated costs. This complexity score helps enforce rate limits.
The algorithm is based on a GitHub document, with some modifications.
Details#
-
Scalars usually don’t add any complexity score. Very few are marked as expensive, and then their score is
2
. -
Objects add
1
+ their fields' complexity. Only selected fields and their dependencies are taken into the calculation. -
Lists multiply the cost of a list item (object) by the
limit
. In case there’s nolimit
, a default of10
is assumed for the sake of complexity calculation. -
Connections work like collections, but the limit is specified in either the
first
orlast
argument. In their structure, there’s a list ofedges
, which doesn’t add complexity points, as the multiplication happens on the connection level.
Simple example#
Let’s say we have a query like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
markets(limit: 50) { # 50 * (1 + 110)
id
name
assignedToCountries(limit: 10) { # 10 * (1 + 10)
code
continent
name
states(limit: 10) { # 10 * 1
id
}
}
}
}
Up to 50 markets can be returned, each one with a list of countries (limited to 10), each potential country with up to 10 states.
Now, counting from the deepest level:
states
will return up to 10 objects, each object is worth 1 complexity point, because they have only scalars inside;assignedToCountries
will return up to 10 countries, each country object worth 1 point for being an object, plus the child complexity of 10, for a total of 110 points.markets
will now be worth 1 + 110 per object, which multiplied by the limit makes a total of 5550 points.
More complex example#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
productVariantConnection(last: 100) { # 100 * (1 + 1 + 114)
totalCount
pageInfo { # 1
hasPreviousPage
startCursor
}
edges { # no additional cost, it's part of the connection
cursor
node { # 1 + 3 + 110
id
...cost # 3
...attributes @include(if: true) # 110
}
}
}
}
fragment cost on ProductVariant {
unitCost { # 1 + 1 + 1
currency { # 1
code
}
formattedValue
converted { # 1
formattedValue
}
conversionDate
conversionRate
}
}
fragment attributes on ObjectWithAttributes {
attributes { # 10 * (1 + 10)
description
... on MappedAttribute {
id
}
elements { # 10
key
description
... on AttributeStringElement {
value
}
}
}
}
Now the calculations starting from the fragments:
- The cost fragment consists of one object with another two objects nested in it, so its complexity score is 3.
- The attributes fragment returns a list with a list embedded in it. Since there are no limit arguments, a default value of 10 is taken on both levels, so it makes a total of 110.
- Each
ProductVariant
object is now worth 114 complexity points,edges
list doesn't add complexity, andpageInfo
adds only 1. Multiplied by the limit from thelast
argument (100), the total complexity becomes 11600.
Expensive scalar example#
1
2
3
4
5
6
7
{
categories(limit: 100) { # 100 * (1 + 2)
id
name
displaySortType # expensive = 2
}
}
Here the displaySortType
is marked as "expensive", because it has a complex formula. Other than that, the calculation is pretty basic: each category object gets a score of 1 + 2, and there are up to 100 categories returned, for a total of 300.
Individual query complexity limit#
The maximum complexity of any individual query to the Integration API is also limited, and the limit is 100 000 complexity points.