Kong Gateway evaluates GraphQL query costs by introspecting the endpoint’s GraphQL schema and applying cost decoration to parts of the schema tree.
Initially all nodes start with zero cost, with any operation at cost 1.
You can add rate limiting constraints on any subtree.
If a subtree is omitted, then the rate limit window applies to the whole tree, meaning any operation.
The GraphQL Rate Limiting Advanced plugin exposes two strategies for approximating the cost of a GraphQL query, configurable via config.cost_strategy
:
-
default
: The default strategy tries to estimate cost on queries by counting the nesting of nodes.
-
node_quantifier
: Useful for GraphQL schemas that enforce quantifier arguments on any connection.
The default strategy is meant as a good middle ground for general GraphQL
queries, where it’s difficult to assert a clear cost strategy, so every operation
has a cost of 1.
For example:
query { # + 1
allPeople { # + 1
people { # + 1
name # + 1
}
}
}
# total cost: 4
Default node costs can be defined by decorating the schema:
type_path
|
mul_arguments
|
mul_constant
|
add_arguments
|
add_constant
|
Query.allPeople
|
[“first”]
|
1
|
[]
|
1
|
Person.vehicleConnection
|
[“first”]
|
1
|
[]
|
1
|
In this example, vehicleConnection
weight (4) is applied 10 times, and the total weight of it (40) 20 times, which gives us a rough 800:
query { # + 1
allPeople(first:20) { # * 20 + 1
people { # + 1
name # + 1
vehicleConnection(first:10) { # * 10 + 1
vehicles { # + 1
id # + 1
name # + 1
cargoCapacity # + 1
}
}
}
}
}
# total cost: ((((4 * 10 + 1) + 1) + 1) * 20 + 1) + 1 = 862
Cost constants can be atomically defined as:
type_path
|
mul_arguments
|
mul_constant
|
add_arguments
|
add_constant
|
Query.allPeople
|
[“first”]
|
2
|
[]
|
2
|
Person.vehicleConnection
|
[“first”]
|
1
|
[]
|
5
|
Vehicle.name
|
[]
|
1
|
[]
|
8
|
In this example, Vehicle.name
and Person.vehicleConnection
have specific weights of 8 and 5 respectively.
allPeople
has a weight of 2, and also has double its weight when multiplied by arguments.
query { # + 1
allPeople(first:20) { # 2 * 20 + 2
people { # + 1
name # + 1
vehicleConnection(first:10) { # * 10 + 5
vehicles { # + 1
id # + 1
name # + 8
cargoCapacity # + 1
}
}
}
}
}
# total cost: ((((11 * 10 + 5) + 1) + 1) * 2 * 20 + 2) + 1 = 4683
This strategy is useful for GraphQL schemas that enforce quantifier arguments on
any connection, providing a good approximation on the number of nodes visited for satisfying a query.
Any query without decorated quantifiers has a cost of 1.
This strategy is roughly based on GitHub’s GraphQL resource limits.
Let’s use the following example configuration:
type_path
|
mul_arguments
|
mul_constant
|
add_arguments
|
add_constant
|
Query.allPeople
|
[“first”]
|
1
|
[]
|
1
|
Person.vehicleConnection
|
[“first”]
|
1
|
[]
|
1
|
Vehicle.filmConnection
|
[“first”]
|
1
|
[]
|
1
|
Film.characterConnection
|
[“first”]
|
1
|
[]
|
1
|
Here’s what it looks like in a query:
query {
allPeople(first:100) { # 1
people {
name
vehicleConnection(first:10) { # 100
vehicles {
name
filmConnection(first:5) { # 10 * 100
films{
title
characterConnection(first:50) { # 5 * 10 * 100
characters {
name
}
}
}
}
}
}
}
}
}
# total cost: 1 + 100 + 10 * 100 + 5 * 10 * 100 = 6101
In the example above:
-
allPeople
returns 100 nodes and has been called once
-
vehicleConnection
returns 10 nodes and has been called 100 times
-
filmConnection
returns 5 nodes and has been called 10 * 100 times
-
characterConnection
returns 50 nodes and has been called 5 * 10 * 100 times
Specific costs per node can be specified by adding a constant:
type_path
|
mul_arguments
|
mul_constant
|
add_arguments
|
add_constant
|
Query.allPeople
|
[“first”]
|
1
|
[]
|
1
|
Person.vehicleConnection
|
[“first”]
|
1
|
[]
|
42
|
Vehicle.filmConnection
|
[“first”]
|
1
|
[]
|
1
|
Film.characterConnection
|
[“first”]
|
1
|
[]
|
1
|
For example:
query {
allPeople(first:100) { # 1
people {
name
vehicleConnection(first:10) { # 100 * 42
vehicles {
name
filmConnection(first:5) { # 10 * 100
films{
title
characterConnection(first:50) { # 5 * 10 * 100
characters {
name
}
}
}
}
}
}
}
}
}
# total cost: 1 + 100 * 42 + 10 * 100 + 5 * 10 * 100 = 10201
The GraphQL cost decoration schema includes the following parameters:
Form parameter
|
Default
|
Description
|
type_path
|
none
|
Path to the node to decorate.
|
add_constant
|
1
|
Node weight when added.
|
add_arguments
|
[]
|
List of arguments to add to add_constant .
|
mul_constant
|
1
|
Node weight multiplier value.
|
mul_arguments
|
[]
|
List of arguments that multiply weight.
|