GraphQL resource limitations

As with any public API, the OnSign GraphQL API protects against excessive or abusive calls to our servers.

Node limit

To pass schema validation, all GraphQL API calls must meet these standards:

  • Clients must supply a first or last argument on any connection.
  • Values of first and last must be within 1-100.
  • Individual calls cannot request more than 100,000 total nodes and depth greater than 30.

Calculating nodes in a call

These two examples show how to calculate the total nodes in a call.

  1. Simple query:

    query {
      organization {
        playerGroups(first: 50) {
          nodes {
            name
    
            players(first: 10) {
              totalCount
    
              nodes {
                id
                name
              }
            }
          }
        }
      }
    }
    

    Calculation:

    50         = 50 player groups
    +
    50 x 10    = 500 player group players
    
              = 550 total nodes
    
  2. Complex query:

    query {
      organization {
        playerGroups(first: 50) {
          nodes {
            players(first: 10) {
              nodes {
                loop(name: PRIMARY) {
                  items(first: 20) {
                    edges {
                      id
                      node {
                        id
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    

    Calculation:

    50            = 50 player groups
    +
    50 x 20       = 1000 players
    +
    50 x 20 x 10  = 10,000 playloop items
    
                  = 11,050 total nodes
    

Max query depth limit

The GraphQL API limits the depth of a query to 30 levels. This means that a query can't have more than 30 nested levels of connections.

Here's an example of a query with a depth of 3:

query {                       # 0 (depth root)
  organization {              # 1
    dataFeeds(first: 1) {     # 2
      nodes {
        name
        columns(first: 1) {   # 3
          nodes {
            name
          }
        }
      }
    }
    users(first: 1) {         # 2
      nodes {
        name
      }
    }
  }
}

Rate limit

GraphQL calls are rate limited based on the server cost of each requested query.

To accurately represent the server cost of a query, the GraphQL API calculates a call's rate limit score based on a normalized scale of points. A query's score factors in first and last arguments on a parent connection and its children.

  • The formula uses the first and last arguments on a parent connection and its children to pre-calculate the potential load on the API servers.
  • Each new connection has its own point value. Points are combined with other points from the call into an overall rate limit score.

The GraphQL API rate limit is 5,000 points per hour.

Note that 5,000 points per hour is not the same as 5,000 calls per hour: a GraphQL API call can result in multiple points being consumed, depending on its complexity.

Note: The current formula and rate limit are subject to change as we observe how developers use the GraphQL API.

Returning a call's rate limit status

With the GraphQL API, you can check the rate limit status by querying fields on the rateLimit object:

query {
  organization {
    id
    name
  }

  rateLimit {
    limit
    cost
    remaining
    resetAt
  }
}
  • The limit field returns the maximum number of points the client is permitted to consume in a 60-minute window.
  • The cost field returns the point cost for the current call that counts against the rate limit.
  • The remaining field returns the number of points remaining in the current rate limit window.)
  • The resetAt field returns the time at which the current rate limit window resets in UTC epoch seconds.

Calculating a rate limit score before running the call

Querying the rateLimit object returns a call's score, but running the call counts against the limit. To avoid this dilemma, you can calculate the score of a call before you run it. The following calculation works out to roughly the same cost that rateLimit { cost } returns.

  • Add up the number of requests needed to fulfill each unique connection in the call. Assume every request will reach the first or last argument limits.
  • Divide the number by 100 and round the result to get the final aggregate cost. This step normalizes large numbers.
Note: The minimum cost of a call to the GraphQL API is 1, representing a single request.

Here's an example query and score calculation:

query {
  organization {
    id

    playerGroups(first: 100) {
      nodes {
        id

        players(first: 50) {
          nodes {
            id

            loop(name: PRIMARY) {
              items(first: 10) {
                edges {
                  id
                }
              }
            }
          }
        }
      }
    }
  }
}

This query requires 5,201 requests to fulfill:

  • Although we're returning 100 player groups, the API has to connect to the organizations's account once to get the organization and then list of player groups. So, requests for organization and player groups = 2
  • Although we're returning 50 players, the API has to connect to each of the 100 player groups to get the list of players. So, requests for players = 100
  • Although we're returning 10 playloop items, the API has to connect to each of the 5,000 potential total players to get the list of playloop items. So, requests for playloop items = 5,000
  • Total = 5,200

Dividing by 100 and rounding gives us the final score of the query: 52

Player Update Throttling

In order to reduce player bandwitdth, requests that modify player content may be aggregated into 60 second time frames, meaning it may take some time to see some changes reflected in your player.

Overview