Request Complexity
Overview
Request complexity refers to the computational cost and resource usage of executing a GraphQL query. ecause GraphQL lets clients request deeply nested and complex data structures in a single query, complexity must be managed to avoid overloading the server.
Scoring complexity
Common factors that increase complexity are operation, depth, and type. For example:
- Operation: Mutations are often more complex than queries due to data writes and consistency requirements.
- Depth: Deeply nested queries are more complex than shallow ones.
- Type: Objects with multiple fields or relationships to other objects are more complex than primitive types such as scalars.
Highnote manages the complexity of its API with complexity scoring, rate limiting, and pagination.
Type and pattern costs
Query operation types are scored as follows:
- Query: Query cost is based on the types and fields requested.
- Mutation: Mutations have a base cost of 10, plus any additional costs based on the types and fields requested.
Other types and patterns are scored as follows:
| Type / Pattern | Description | Cost |
|---|---|---|
| Object | Type with a defined set of fields (e.g., a User with id, name, email fields) | 1 point |
| Interface | Template type that defines required fields other types must implement. Uses maximum type complexity (where only the most expensive type requested is counted). | 1 point |
| Union | Type that can be one of several object types. Uses maximum type complexity. | 1 point |
| Scalar | Primitive type like String, Int, Boolean. Cost is accounted for in the object it belongs to. | 0 points |
| Enum | User-defined type with a fixed set of allowed values. Cost is accounted for in the object it belongs to. | 0 points |
| Connection | Pattern for pagination, typically implemented as an object type with edges and nodes. Defines how different types of data are connected and how they can be queried. | 2 points + number of objects requested |
The fields cursor and pageInfo are intrinsic to the connection pattern and have no separate complexity cost.
Simple example
The following example demonstrates a simple request complexity calculation:
query ListCardProducts {
cardProducts(first: 10) {
# Connection 2 + 10 items
pageInfo {
# PageInfo object 0 point
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
# Edges field - 0 point
cursor # String - 0 point
node {
# Node field in connection - 0 point
id # String - 0 point
name # String - 0 point
vertical # String - 0 point
features {
# Object - 1 point
enabled # Boolean - 0 point
}
}
}
}
}
2 + 10(1)
Nested example
The following example demonstrates a more complex request complexity calculation that includes nested connection objects to illustrate how pagination cost can multiply:
query LookupStatement($id: ID!) {
node(id: $id) {
# Object 1 point
... on SecuredDepositCommercialCreditCardFinancialAccountStatement {
statementEntries(first: 20) {
# Connection 2 + 20 items
edges {
# Edges field - 0 point
node {
# Node field in connection - 0 point
ledgerEntry {
# Object - 1 point
__typename # String - 0
id # ID - 0 point
ledger {
# Object - 1 point
ledgerEntries(first: 20) {
# Connection 2 + 20 items
edges {
# Edges field - 0 point
node {
# Node field in connection - 0 point
amount {
# 1 Object - 1 point
value # 0 UnsignedInt - 0 point
}
}
}
}
}
}
}
}
}
}
}
}
1 + 2 + 20(1 + 1 + 2 + 20(1)) = 483
Testing request costs
Every Highnote GraphQL API response includes the request cost under the extensions field. We recommend that you test the cost of your queries in the API Explorer.
The following example represents a request cost response in an API request that is not rate-limited:
{
"data": {},
"errors": {},
"extensions": {
"rateLimit": {
"limit": 100,
"cost": 5,
"remaining": 95
}
}
}