{"meta":{"title":"Rate limits and query limits for the GraphQL API","intro":"The GitHub GraphQL API has limitations in place to protect against excessive or abusive calls to GitHub's servers.","product":"GraphQL API","breadcrumbs":[{"href":"/en/enterprise-cloud@latest/graphql","title":"GraphQL API"},{"href":"/en/enterprise-cloud@latest/graphql/overview","title":"Overview"},{"href":"/en/enterprise-cloud@latest/graphql/overview/rate-limits-and-query-limits-for-the-graphql-api","title":"Rate and query limits"}],"documentType":"article"},"body":"# Rate limits and query limits for the GraphQL API\n\nThe GitHub GraphQL API has limitations in place to protect against excessive or abusive calls to GitHub's servers.\n\n## Primary rate limit\n\nThe 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.\n\nThe REST API also has a separate primary rate limit. For more information, see [Rate limits for the REST API](/en/enterprise-cloud@latest/rest/using-the-rest-api/rate-limits-for-the-rest-api).\n\nIn general, you can calculate your primary rate limit for the GraphQL API based on your method of authentication:\n\n* *For users*: 5,000 points per hour per user. This includes requests made with a personal access token as well as requests made by a GitHub App or OAuth app on behalf of a user that authorized the app. Requests made on a user's behalf by a GitHub App that is owned by a GitHub Enterprise Cloud organization have a higher rate limit of 10,000 points per hour. Similarly, requests made on your behalf by an OAuth app that is owned or approved by a GitHub Enterprise Cloud organization have a higher rate limit of 10,000 points per hour if you are a member of the GitHub Enterprise Cloud organization.\n* *For GitHub App installations not on a GitHub Enterprise Cloud organization or enterprise*: 5,000 points per hour per installation. Installations that have more than 20 repositories receive another 50 points per hour for each repository. Installations that are on an organization that have more than 20 users receive another 50 points per hour for each user. The rate limit cannot increase beyond 12,500 points per hour. The rate limit for user access tokens (as opposed to installation access tokens) are dictated by the primary rate limit for users.\n* *For GitHub App installations on a GitHub Enterprise Cloud organization or enterprise*: 10,000 points per hour per installation. The rate limit for user access tokens (as opposed to installation access tokens) are dictated by the primary rate limit for users.\n* *For OAuth apps*: 5,000 points per hour, or 10,000 points per hour if the app is owned by a GitHub Enterprise Cloud organization. This only applies when the app uses their client ID and client secret to request public data. The rate limit for OAuth access tokens generated by a OAuth app are dictated by the primary rate limit for users.\n* *For `GITHUB_TOKEN` in GitHub Actions workflows*: 1,000 points per hour per repository. For requests to resources that belong to an enterprise account on GitHub.com, the limit is 15,000 points per hour per repository.\n\nYou 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.\n\n### Checking the status of your primary rate limit\n\nYou can use the headers that are sent with each response to determine the current status of your primary rate limit.\n\n| Header name             | Description                                                                                                    |\n| ----------------------- | -------------------------------------------------------------------------------------------------------------- |\n| `x-ratelimit-limit`     | The maximum number of points that you can use per hour                                                         |\n| `x-ratelimit-remaining` | The number of points remaining in the current rate limit window                                                |\n| `x-ratelimit-used`      | The number of points you have used in the current rate limit window                                            |\n| `x-ratelimit-reset`     | The time at which the current rate limit window resets, in UTC epoch seconds                                   |\n| `x-ratelimit-resource`  | The rate limit resource that the request counted against. For GraphQL requests, this will always be `graphql`. |\n\nYou 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.\n\n```graphql\nquery {\n  viewer {\n    login\n  }\n  rateLimit {\n    limit\n    remaining\n    used\n    resetAt\n  }\n}\n```\n\n| Field       | Description                                                                  |\n| ----------- | ---------------------------------------------------------------------------- |\n| `limit`     | The maximum number of points that you can use per hour                       |\n| `remaining` | The number of points remaining in the current rate limit window              |\n| `used`      | The number of points you have used in the current rate limit window          |\n| `resetAt`   | The time at which the current rate limit window resets, in UTC epoch seconds |\n\n### Returning the point value of a query\n\nYou can return the point value of a query by querying the `cost` field on the `rateLimit` object:\n\n```graphql\nquery {\n  viewer {\n    login\n  }\n  rateLimit {\n    cost\n  }\n}\n```\n\n### Predicting the point value of a query\n\nYou can also roughly calculate the point value of a query before you make the query.\n\n1. 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.\n2. 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.\n\n> \\[!NOTE]\n> The minimum point value of a call to the GraphQL API is **1**.\n\nHere's an example query and score calculation:\n\n```graphql\nquery {\n  viewer {\n    login\n    repositories(first: 100) {\n      edges {\n        node {\n          id\n\n          issues(first: 50) {\n            edges {\n              node {\n                id\n\n                labels(first: 60) {\n                  edges {\n                    node {\n                      id\n                      name\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nThis query requires 5,101 requests to fulfill:\n\n* Although we're returning 100 repositories, the API has to connect to the viewer's account **once** to get the list of repositories. So, requests for repositories = **1**\n* Although we're returning 50 issues, the API has to connect to each of the **100** repositories to get the list of issues. So, requests for issues = **100**\n* Although we're returning 60 labels, the API has to connect to each of the **5,000** potential total issues to get the list of labels. So, requests for labels = **5,000**\n* Total = **5,101**\n\nDividing by 100 and rounding gives us the final score of the query: **51**\n\n## Secondary rate limits\n\nIn addition to primary rate limits, GitHub enforces secondary rate limits in order to prevent abuse and keep the API available for all users.\n\nYou may encounter a secondary rate limit if you:\n\n* *Make too many concurrent requests.* No more than 100 concurrent requests are allowed. This limit is shared across the REST API and GraphQL API.\n* *Make too many requests to a single endpoint per minute.* No more than 900 points per minute are allowed for REST API endpoints, and no more than 2,000 points per minute are allowed for the GraphQL API endpoint. For more information about points, see [Calculating points for the secondary rate limit](#calculating-points-for-the-secondary-rate-limit).\n* *Make too many requests per minute.* No more than 90 seconds of CPU time per 60 seconds of real time is allowed. No more than 60 seconds of this CPU time may be for the GraphQL API. You can roughly estimate the CPU time by measuring the total response time for your API requests.\n* *Make too many requests that consume excessive compute resources in a short period of time.*\n* *Create too much content on GitHub in a short amount of time.* In general, no more than 80 content-generating requests per minute and no more than 500 content-generating requests per hour are allowed. Some endpoints have lower content creation limits. Content creation limits include actions taken on the GitHub web interface as well as via the REST API and GraphQL API.\n* *Make too many OAuth access token requests in a short period of time.* No more than 2,000 OAuth access token requests per hour are allowed for GitHub Apps and OAuth apps.\n\nThese secondary rate limits are subject to change without notice. You may also encounter a secondary rate limit for undisclosed reasons.\n\n### Calculating points for the secondary rate limit\n\nSome 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.\n\n| Request                                                    | Points |\n| ---------------------------------------------------------- | ------ |\n| GraphQL requests without mutations                         | 1      |\n| GraphQL requests with mutations                            | 5      |\n| Most REST API `GET`, `HEAD`, and `OPTIONS` requests        | 1      |\n| Most REST API `POST`, `PATCH`, `PUT`, or `DELETE` requests | 5      |\n\nSome REST API endpoints have a different point cost that is not shared publicly.\n\n## Exceeding the rate limit\n\nIf 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.\n\nIf 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.\n\nContinuing to make requests while you are rate limited may result in the banning of your integration.\n\n## Staying under the rate limit\n\nTo avoid exceeding a rate limit, you should pause at least 1 second between mutative requests and avoid concurrent requests.\n\nYou should also subscribe to webhook events instead of polling the API for data. For more information, see [Webhooks documentation](/en/enterprise-cloud@latest/webhooks).\n\nYou 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](/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise).\n\n## Node limit\n\nTo pass [schema](/en/enterprise-cloud@latest/graphql/guides/introduction-to-graphql#schema) validation, all GraphQL API [calls](/en/enterprise-cloud@latest/graphql/guides/forming-calls-with-graphql) must meet these standards:\n\n* Clients must supply a `first` or `last` argument on any [connection](/en/enterprise-cloud@latest/graphql/guides/introduction-to-graphql#connection).\n* Values of `first` and `last` must be within 1-100.\n* Individual calls cannot request more than 500,000 total [nodes](/en/enterprise-cloud@latest/graphql/guides/introduction-to-graphql#node).\n\n### Calculating nodes in a call\n\nThese two examples show how to calculate the total nodes in a call.\n\n1. Simple query:\n\n   <pre>query {\n     viewer {\n       repositories(first: <span class=\"redbox\">50</span>) {\n         edges {\n           repository:node {\n             name\n\n             issues(first: <span class=\"greenbox\">10</span>) {\n               totalCount\n               edges {\n                 node {\n                   title\n                   bodyHTML\n                 }\n               }\n             }\n           }\n         }\n       }\n     }\n   }</pre>\n\n   Calculation:\n\n   <pre><span class=\"redbox\">50</span>         = 50 repositories\n    +\n   <span class=\"redbox\">50</span> x <span class=\"greenbox\">10</span>  = 500 repository issues\n\n               = 550 total nodes</pre>\n\n2. Complex query:\n\n   <pre>query {\n     viewer {\n       repositories(first: <span class=\"redbox\">50</span>) {\n         edges {\n           repository:node {\n             name\n\n             pullRequests(first: <span class=\"greenbox\">20</span>) {\n               edges {\n                 pullRequest:node {\n                   title\n\n                   comments(first: <span class=\"bluebox\">10</span>) {\n                     edges {\n                       comment:node {\n                         bodyHTML\n                       }\n                     }\n                   }\n                 }\n               }\n             }\n\n             issues(first: <span class=\"greenbox\">20</span>) {\n               totalCount\n               edges {\n                 issue:node {\n                   title\n                   bodyHTML\n\n                   comments(first: <span class=\"bluebox\">10</span>) {\n                     edges {\n                       comment:node {\n                         bodyHTML\n                       }\n                     }\n                   }\n                 }\n               }\n             }\n           }\n         }\n       }\n\n       followers(first: <span class=\"bluebox\">10</span>) {\n         edges {\n           follower:node {\n             login\n           }\n         }\n       }\n     }\n   }</code></pre>\n\n   Calculation:\n\n   <pre><span class=\"redbox\">50</span>              = 50 repositories\n    +\n   <span class=\"redbox\">50</span> x <span class=\"greenbox\">20</span>       = 1,000 pullRequests\n    +\n   <span class=\"redbox\">50</span> x <span class=\"greenbox\">20</span> x <span class=\"bluebox\">10</span> = 10,000 pullRequest comments\n    +\n   <span class=\"redbox\">50</span> x <span class=\"greenbox\">20</span>       = 1,000 issues\n    +\n   <span class=\"redbox\">50</span> x <span class=\"greenbox\">20</span> x <span class=\"bluebox\">10</span> = 10,000 issue comments\n    +\n   <span class=\"bluebox\">10</span>              = 10 followers\n\n                    = 22,060 total nodes</pre>\n\n## Timeouts\n\nIf 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\".\n\nWhen this happens, you may receive either a `502` or `504` status code. Both status codes indicate that your request timed out.\n\nGitHub reserves the right to change the timeout window to protect the speed and reliability of the API.\n\nYou can check the status of the GraphQL API at [githubstatus.com](https://www.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 tips on improving query performance, see [Query optimization strategies](#query-optimization-strategies).\n\nIf a timeout occurs for any of your API requests, additional points will be deducted from your primary rate limit for the next hour to protect the speed and reliability of the API.\n\n## Other resource limits\n\nTo protect the speed and reliability of the API, GitHub also enforces other resource limitations. If your GraphQL query consumes too many resources, GitHub will terminate the request and return partial results along with an error indicating that resource limits were exceeded.\n\n**Examples of queries that may exceed resource limits:**\n\n* Requesting thousands of objects or deeply nested relationships in a single query.\n* Using large `first` or `last` arguments in multiple connections simultaneously.\n* Fetching extensive details for each object, such as all comments, reactions, and related issues for every repository.\n\n## Query optimization strategies\n\n* **Limit the number of objects**: Use smaller values for `first` or `last` arguments and paginate through results.\n* **Reduce query depth**: Avoid requesting deeply nested objects unless necessary.\n* **Filter results**: Use arguments to filter data and return only what you need.\n* **Split large queries**: Break up complex queries into multiple simpler queries.\n* **Request only required fields**: Select only the fields you need, rather than requesting all available fields.\n\nBy following these strategies, you can reduce the likelihood of hitting resource limits and improve the performance and reliability of your API requests."}