API limits
Introduction
Limiting the depth and/or rate of API requests can help prevent API performance issues caused by malicious or poorly implemented queries.
API limit types
API limits are defined by role (e.g. anonymous, user) and can restrict request rate, depth, or both. Unique request parameters can include IP address or session variables (x-hasura-user-id, x-hasura-org-id, etc.)
Rate limits
Restricts number of GraphQL operations per minute. This uses a sliding window approach. This means whenever Hasura Pro receives a request, it will count the rate of that client starting from the current time to last one minute.
By default, the rate-limit happens on the role_name
i.e the value provided in X-HASURA-ROLE
. But you can also
combine additional unique parameters for more granularity.
The Unique Parameters that are provided are:
- IP Address
- Session Variables
You can choose any one of the above parameters to rate limit the requests.
Note: If you set a Unique Parameter
then the combination of both the role_name
and the Unique Parameter
will
be used to rate-limit requests.
Example:
If you rate-limit using the role_name
and set the unique parameter for the rate-limit as IP Address
, then rate-limit
will be applied depending on both those parameteres. i.e If the requests come from a different role but same IP address
will NOT be rate limited
Depth limits
Restricts a GraphQL operation based on its depth, preventing deeply nested queries.
GraphQL introspection queries are excluded from depth limits.
You can see various queries as examples and their depths here:
# depth = 1
query deep1_1 {
viewer {
name
}
}
query deep1_2 {
viewer {
... on User {
name
}
}
}
# depth = 2
query deep2 {
viewer {
albums {
title
}
}
}
# depth = 3
query deep3 {
viewer {
albums {
...musicInfo
songs {
...musicInfo
}
}
}
}
fragment musicInfo on Music {
id
title
artists
}
Node limits
Restricts a GraphQL operation based on the number of nodes. This helps in limiting the number of different pieces of related data to be fetched.
A node is defined as a field with a selection set.
For example, in the below query the number of nodes is 3 and they are author
, articles
and homepage_entries
.
{
author {
name
articles {
id
title
}
}
homepage_entries {
article_id
}
}
Time limits
Restricts the time that a GraphQL operation is allowed to take. The duration is specified in seconds.
Any upstream database queries are also cancelled for supported sources. Currently, cancellation only works for Postgres sources.
All Free tier and Standard tier Hasura Cloud projects get a time limit of 60 seconds. When the cloud limit is hit, the
error contains the code tenant-time-limit-exceeded
in the error message.
Batch Limits
Restricts the number of GraphQL operations in a batched request.
For example, the below request has 3 query operations which will not be allowed if the batch limit is set to 2.
query query1 {
artists {
name
albums {
name
}
}
}
query query2 {
playlist {
name
songs {
name
}
}
}
query query3 {
songs {
name
artists {
name
}
}
}
Manage API limits
API limits can have a global or per role configuration. If an incoming request does not contain a valid role then the global limit is applied.
All API limits are not applied for the admin role, and depth limits are NOT applied to introspection queries.
Metadata specification
Hasura provides two metadata API's to manage API limits
Setting API limits
You can configure api limits using the set_api_limits
API.
type: set_api_limits
args:
disabled: # Optional Field (Either True or False, The value is False by default)
depth_limit: # Optional API Limit
global: # Mandatory Field
per_role: # Optional Field
<role_name>: <limit value> # Eg: user: 5
node_limit: # Optional API Limit
global: # Mandatory Field
per_role: # Optional Field
<role_name>: <limit value> # Eg: user: 5
rate_limit: # Optional API Limit
global: # Mandatory Field
unique_params: # Optional Field, Can either be IP Address or Session variables
max_reqs_per_min: # Mandatory Field
per_role: # Optional Field
<role_name>:
max_reqs_per_min: # Mandatory Field
unique_params: # Optional Field
time_limit: # Optional API Limit
global: # Mandatory Field
per_role: # Optional Field
<role_name>: <limit value> # Eg: user: 5
batch_limit: # Optional API Limit
global: # Mandatory Field
per_role: # Optional Field
<role_name>: <limit value> # Eg: user: 5
In the above metadata spec:
- The API Limits are
Enabled
by default, i.e the default value ofdisabled
isFalse
- When
disabled
isFalse
and none of the API Limits are set then no API limits are applied. - The
global
field in all the API Limits is mandatory, and is used as the default API limit if noper_role
option is set for the user. - The
per_role
can be used to override theglobal
API Limit value - For
rate_limit
if nounique_params
are provided then, the requests will be rate-limited on therole_name
i.e theX-HASURA-ROLE
that is used to issue the request
Example Metadata Spec:
type: set_api_limits
args:
disabled: false
depth_limit:
global: 5
per_role:
user: 7
node_limit:
global: 3
per_role:
user: 10
rate_limit:
global:
unique_params: IP
max_reqs_per_min: 10
per_role:
anonymous:
max_reqs_per_min: 10
unique_params: 'ip'
user:
unique_params:
- x-hasura-user-id
- x-hasura-team-id
max_reqs_per_min: 20
time_limit:
global: 10
per_role:
user: 5
batch_limit:
global: 5
per_role:
user: 2
Removing API limits
You can remove all the api limits that have been set using remove_api_limit
API.
type: remove_api_limits
args: {}