Rate limits and node limits for the GraphQL API - GitHub Docs (original) (raw)

The GitHub GraphQL API has limitations in place to protect against excessive or abusive calls to GitHub's servers.

Node limit

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

Calculating nodes in a call

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

  1. Simple query:
    query {
    viewer {
    repositories(first: 50) {
    edges {
    repository:node {
    name
    issues(first: 10) {
    totalCount
    edges {
    node {
    title
    bodyHTML
    }
    }
    }
    }
    }
    }
    }
    }
    Calculation:
    50 = 50 repositories
  1. Complex query:
    query {
    viewer {
    repositories(first: 50) {
    edges {
    repository:node {
    name
    pullRequests(first: 20) {
    edges {
    pullRequest:node {
    title
    comments(first: 10) {
    edges {
    comment:node {
    bodyHTML
    }
    }
    }
    }
    }
    }
    issues(first: 20) {
    totalCount
    edges {
    issue:node {
    title
    bodyHTML
    comments(first: 10) {
    edges {
    comment:node {
    bodyHTML
    }
    }
    }
    }
    }
    }
    }
    }
    }
    followers(first: 10) {
    edges {
    follower:node {
    login
    }
    }
    }
    }
    }
    Calculation:
    50 = 50 repositories

Primary rate limit

The GraphQL API assigns points to each query and limits the points that you can use within a specific amount of time. This limit helps prevent abuse and denial-of-service attacks, and ensures that the API remains available for all users.

The REST API also has a separate primary rate limit. For more information, see Rate limits for the REST API.

In general, you can calculate your primary rate limit for the GraphQL API based on your method of authentication:

You can check the point value of a query or calculate the expected point value as described in the following sections. The formula for calculating points and the rate limit are subject to change.

Checking the status of your primary rate limit

You can use the headers that are sent with each response to determine the current status of your primary rate limit.

Header name Description
x-ratelimit-limit The maximum number of points that you can use per hour
x-ratelimit-remaining The number of points remaining in the current rate limit window
x-ratelimit-used The number of points you have used in the current rate limit window
x-ratelimit-reset The time at which the current rate limit window resets, in UTC epoch seconds
x-ratelimit-resource The rate limit resource that the request counted against. For GraphQL requests, this will always be graphql.

You can also query the rateLimit object to check your rate limit. When possible, you should use the rate limit response headers instead of querying the API to check your rate limit.

query {
  viewer {
    login
  }
  rateLimit {
    limit
    remaining
    used
    resetAt
  }
}
Field Description
limit The maximum number of points that you can use per hour
remaining The number of points remaining in the current rate limit window
used The number of points you have used in the current rate limit window
resetAt The time at which the current rate limit window resets, in UTC epoch seconds

Returning the point value of a query

You can return the point value of a query by querying the cost field on the rateLimit object:

query {
  viewer {
    login
  }
  rateLimit {
    cost
  }
}

Predicting the point value of a query

You can also roughly calculate the point value of a query before you make the query.

  1. 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.
  2. Divide the number by 100 and round the result to the nearest whole number to get the final aggregate point value. This step normalizes large numbers.

Note

The minimum point value of a call to the GraphQL API is 1.

Here's an example query and score calculation:

query {
  viewer {
    login
    repositories(first: 100) {
      edges {
        node {
          id

          issues(first: 50) {
            edges {
              node {
                id

                labels(first: 60) {
                  edges {
                    node {
                      id
                      name
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

This query requires 5,101 requests to fulfill:

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

Secondary rate limits

In addition to primary rate limits, GitHub enforces secondary rate limits in order to prevent abuse and keep the API available for all users.

You may encounter a secondary rate limit if you:

These secondary rate limits are subject to change without notice. You may also encounter a secondary rate limit for undisclosed reasons.

Calculating points for the secondary rate limit

Some secondary rate limits are determined by the point values of requests. For GraphQL requests, these point values are separate from the point value calculations for the primary rate limit.

Request Points
GraphQL requests without mutations 1
GraphQL requests with mutations 5
Most REST API GET, HEAD, and OPTIONS requests 1
Most REST API POST, PATCH, PUT, or DELETE requests 5

Some REST API endpoints have a different point cost that is not shared publicly.

Exceeding the rate limit

If you exceed your primary rate limit, the response status will still be 200, but you will receive an error message, and the value of the x-ratelimit-remaining header will be 0. You should not retry your request until after the time specified by the x-ratelimit-reset header.

If you exceed a secondary rate limit, the response status will be 200 or 403, and you will receive an error message that indicates that you hit a secondary rate limit. If the retry-after response header is present, you should not retry your request until after that many seconds has elapsed. If the x-ratelimit-remaining header is 0, you should not retry your request until after the time, in UTC epoch seconds, specified by the x-ratelimit-reset header. Otherwise, wait for at least one minute before retrying. If your request continues to fail due to a secondary rate limit, wait for an exponentially increasing amount of time between retries, and throw an error after a specific number of retries.

Continuing to make requests while you are rate limited may result in the banning of your integration.

Staying under the rate limit

To avoid exceeding a rate limit, you should pause at least 1 second between mutative requests and avoid concurrent requests.

You should also subscribe to webhook events instead of polling the API for data. For more information, see Webhooks documentation.

You can also stream the audit log in order to view API requests. This can help you troubleshoot integrations that are exceeding the rate limit. For more information, see Streaming the audit log for your enterprise.

Timeouts

If GitHub takes more than 10 seconds to process an API request, GitHub will terminate the request and you will receive a timeout response and a message reporting that "We couldn't respond to your request in time".

GitHub reserves the right to change the timeout window to protect the speed and reliability of the API.

You can check the status of the GraphQL API at githubstatus.com to determine whether the timeout is due to a problem with the API. You can also try to simplify your request or try your request later. For example, if you are requesting a large number of objects in a single request, you can try requesting fewer objects split over multiple queries.