Resource Limitations
The Levain GraphQL API has limitations in place to protect against excessive or abusive calls to Levain's GraphQL servers. A single GraphQL query can potentially generate a huge workload for a server, like thousands of database operations or API calls. In order to limit and keep track of what each GraphQL operation can do, a set of rules are applied to each query and mutation to estimate its complexity and execution time. If a query exceeds the defined limit, an error is thrown.
The resource limitations will change over time as we learn more about the usage patterns of the GraphQL API. To ensure that your application is not affected by these changes, we recommend that you always specify reasonable limits on your queries and mutations.
By design, GraphQL resource limits are always higher than the equivalent REST API limits due to the nature of GraphQL hierarchical queries.
Complexity Limit
The complexity limit is a limit on the computational complexity of a GraphQL query.
It is designed to protect against queries that are computationally expensive and may take a long time to execute.
Currently, the complexity limit is set to 50,000
per query.
The complexity of a GraphQL query is calculated by summing up the complexity of each field in the query. The complexity of a field is calculated by multiplying the complexity of the field by the number of items returned by the field.
Complexity Calculation
NODE = 1
- A node within a connection.FIELD = 1
- A field that loads data from the database within the same row or with simple join.AUTH = 100
- A query that computes the authorization of the user for a resource.API = 500
- A field that loads data from an API that requires additional API calls to load the data.
Different fields in a GraphQL query have different complexity values.
For example,
a field that loads data from the database has a complexity of 1
while a field that loads data from an external API has a complexity of 500
.
query {
# Complexity = 100 + 1 + 603 = 704
# AUTH = 100
organization(orgId: "012345678912") {
# FIELD = 1
name
# Complexity = 100 + 502 + 1 = 603
# AUTH = 100
wallet(walletId: "0") {
# FIELD = 1
name
# Complexity = 500 + 1 + 1 = 502
balanceByAssetId(assetId: "0") {
# API = 500
networkAsset {
# FIELD = 1
name
}
# FIELD = 1
amount
}
}
# Complexity = 10 x 3 = 30
networks(first: 10) {
# NODE = 1
edges {
# NODE = 1
node {
# FIELD = 1
networkId
}
}
}
}
}
The estimated complexity of the query above is 704
which is within the complexity limit of 50,000
.
While the query above could easily be calculated by hand,
it is not always easy to calculate the complexity of a query due to estimations and assumptions that need to be made.
For your convenience, you should always only query what you need, never more and paginate reasonably.
Pagination Limit
The pagination limit is a limit on the number of items
that can be returned in a single page of a paginated query per connection.
This is applied to all paginated queries on top of the complexity limit
to protect against queries that return a large number of items.
Currently, the pagination limit is set to 1000
items per page.
query {
networks(first: 1000) {
# 1000 is the limit per connection
edges {
node {
networkId
assets(first: 1000) {
# 1000 is the limit per connection
edges {
node {
name
}
}
}
}
}
}
}
Although the pagination is within the limit,
the query above will still fail
because the complexity of the query is greater than the complexity limit
which is more than 1000 x 1000
surpassing the 50,000
complexity limit.