跳至主要内容

GraphQL API 的速率限制和查询限制

GitHub GraphQL API 设有限制,以防止对 GitHub 服务器的过度或滥用调用。

主要速率限制

GraphQL API 为每个查询分配点数,并限制在特定时间内可使用的点数。此限制可防止滥用和拒绝服务攻击,并确保 API 对所有用户保持可用。

REST API 也有单独的主要速率限制。了解更多信息,请参阅REST API 的速率限制

通常,您可以根据身份验证方式计算 GraphQL API 的主要速率限制。

  • 对于用户:每位用户每小时 5,000 点。此计数包括使用个人访问令牌的请求以及 GitHub App 或 OAuth 应用代表已授权该应用的用户进行的请求。由 GitHub Enterprise Cloud 组织拥有的 GitHub App 代表用户发出的请求拥有更高的速率限制,为每小时 10,000 点。同样,如果您是该 GitHub Enterprise Cloud 组织的成员,由该组织拥有或批准的 OAuth 应用代表您发出的请求也拥有每小时 10,000 点的更高速率限制。
  • 对于未在 GitHub Enterprise Cloud 组织中的 GitHub App 安装:每个安装每小时 5,000 点。拥有超过 20 个仓库的安装,每个仓库额外获得 50 点/小时。拥有超过 20 位用户的组织安装,每位用户额外获得 50 点/小时。速率限制最高不能超过每小时 12,500 点。用户访问令牌(相对于安装访问令牌)的速率限制受用户的主要速率限制控制。
  • 对于在 GitHub Enterprise Cloud 组织中的 GitHub App 安装:每个安装每小时 10,000 点。用户访问令牌(相对于安装访问令牌)的速率限制受用户的主要速率限制控制。
  • 对于 OAuth 应用:每小时 5,000 点;如果该应用归属于 GitHub Enterprise Cloud 组织,则为每小时 10,000 点。仅在应用使用其 client ID 和 client secret 请求公共数据时适用。OAuth 应用生成的访问令牌的速率限制受用户的主要速率限制控制。
  • 对于 GitHub Actions 工作流中的 GITHUB_TOKEN:每个仓库每小时 1,000 点。对属于 GitHub.com 企业账户的资源发出的请求,每个仓库每小时上限为 15,000 点。

您可以检查查询的点数值,或按照下面章节所述计算预期的点数值。点数计算公式和速率限制可能会更改。

检查主要速率限制的状态

您可以使用每个响应随带的响应头来确定当前主要速率限制的状态。

请求头名称描述
x-ratelimit-limit每小时可使用的最大点数
x-ratelimit-remaining当前速率限制窗口中剩余的点数
x-ratelimit-used当前速率限制窗口中已使用的点数
x-ratelimit-reset当前速率限制窗口重置的时间(UTC epoch 秒)
x-ratelimit-resource计数请求时所使用的速率限制资源。对于 GraphQL 请求,此值始终为 graphql

您也可以查询 rateLimit 对象来检查速率限制。若可能,请使用速率限制响应头而非查询 API 来检查速率限制。

query {
  viewer {
    login
  }
  rateLimit {
    limit
    remaining
    used
    resetAt
  }
}
字段描述
限制每小时可使用的最大点数
剩余当前速率限制窗口中剩余的点数
已使用当前速率限制窗口中已使用的点数
resetAt当前速率限制窗口重置的时间(UTC epoch 秒)

返回查询的点数值

您可以通过查询 rateLimit 对象上的 cost 字段来返回查询的点数值。

query {
  viewer {
    login
  }
  rateLimit {
    cost
  }
}

预测查询的点数值

您也可以在发起查询之前大致计算查询的点数值。

  1. 将调用中每个唯一连接所需的请求次数相加。假设每个请求都达到 firstlast 参数的上限。
  2. 将该数字除以 100,并四舍五入到最接近的整数,以获得最终的聚合点数值。此步骤用于对大数字进行归一化。

注意

对 GraphQL API 的一次调用的最低点数值为 1

以下是示例查询和分数计算

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

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

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

此查询需要 5,101 次请求才能完成

  • 虽然我们返回了 100 个仓库,但 API 只需 **一次** 连接到查看者的帐户即可获取仓库列表。所以,仓库请求数 = 1
  • 虽然我们返回了 50 条 issue,但 API 必须对每个 **100** 个仓库连接一次以获取 issue 列表。所以,issue 请求数 = 100
  • 虽然我们返回了 60 个标签,但 API 必须对每个可能的 **5,000** 条 issue 连接一次以获取标签列表。所以,标签请求数 = 5,000
  • 总计 = 5,101

除以 100 并四舍五入后,得到查询的最终分数:51

次要速率限制

除了主要速率限制之外,GitHub 还实施次要速率限制,以防止滥用并保持 API 对所有用户可用。

如果满足以下情况,您可能会遇到次要速率限制:

  • 发起过多并发请求。 不可超过 100 个并发请求。此限制在 REST API 与 GraphQL API 之间共享。
  • 每分钟对单个端点发出过多请求。 对 REST API 端点每分钟不超过 900 点,对 GraphQL API 端点每分钟不超过 2,000 点。有关点数的更多信息,请参阅次要速率限制的点数计算
  • 每分钟发出过多请求。 每 60 秒真实时间内最多使用 90 秒的 CPU 时间。对 GraphQL API 的 CPU 时间最多不超过 60 秒。您可以通过测量 API 请求的总响应时间来大致估算 CPU 时间。
  • 在短时间内发出大量消耗计算资源的请求。
  • 在短时间内在 GitHub 上创建过多内容。 通常,每分钟不超过 80 次生成内容的请求,每小时不超过 500 次。某些端点的内容创建限制更低。内容创建限制包括通过 GitHub Web 界面以及 REST API 与 GraphQL API 所执行的操作。
  • 在短时间内发出过多 OAuth 访问令牌请求。 对于 GitHub Apps 与 OAuth 应用,每小时不超过 2,000 次 OAuth 访问令牌请求。

这些次要速率限制可在不另行通知的情况下更改。您也可能因未公开的原因而遇到次要速率限制。

计算次要速率限制的点数

某些次要速率限制是根据请求的点数来决定的。对于 GraphQL 请求,这些点数与主要速率限制的点数计算是分开的。

请求点数
无变更的 GraphQL 请求1
带变更的 GraphQL 请求5
大多数 REST API 的 GETHEADOPTIONS 请求1
大多数 REST API 的 POSTPATCHPUTDELETE 请求5

某些 REST API 端点拥有不同的点数费用,且未对外公开。

超过速率限制

如果您超过了主要速率限制,响应状态仍为 200,但会收到错误信息,并且 x-ratelimit-remaining 头的值为 0。在 x-ratelimit-reset 头指定的时间之后才应重试请求。

如果您超过了次要速率限制,响应状态可能为 200403,并会收到指示已触发次要速率限制的错误信息。如果响应头中出现 retry-after,则应在该秒数过去后再重试请求。如果 x-ratelimit-remaining0,则应在 x-ratelimit-reset 头指定的 UTC epoch 秒时间之后才重试请求。否则,请至少等待一分钟后再重试。如果请求仍因次要速率限制而失败,请在重试之间逐渐延长间隔时间,并在达到特定重试次数后抛出错误。

在受到速率限制期间继续发出请求可能导致您的集成被封禁。

保持在速率限制以下

为避免超过速率限制,您应在变更请求之间至少暂停 1 秒,并避免并发请求。

您还应订阅 webhook 事件,而不是轮询 API 获取数据。了解更多,请参阅Webhook 文档

您也可以流式传输审计日志以查看 API 请求。这有助于排查超过速率限制的集成。了解更多,请参阅企业审计日志流式传输

节点限制

要通过模式验证,所有 GraphQL API 调用必须符合以下标准。

  • 客户端在任何连接上必须提供 firstlast 参数。
  • firstlast 的值必须在 1‑100 之间。
  • 单个调用不能请求超过 500,000 个总节点

计算调用中的节点数

以下两个示例演示了如何计算一次调用中的总节点数。

  1. 简单查询

    query {
      viewer {
        repositories(first: 50) {
          edges {
            repository:node {
              name
    
              issues(first: 10) {
                totalCount
                edges {
                  node {
                    title
                    bodyHTML
                  }
                }
              }
            }
          }
        }
      }
    }

    计算

    50         = 50 repositories
     +
    50 x 10  = 500 repository issues
    
                = 550 total nodes
  2. 复杂查询

    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
            }
          }
        }
      }
    }

    计算

    50              = 50 repositories
     +
    50 x 20       = 1,000 pullRequests
     +
    50 x 20 x 10 = 10,000 pullRequest comments
     +
    50 x 20       = 1,000 issues
     +
    50 x 20 x 10 = 10,000 issue comments
     +
    10              = 10 followers
    
                     = 22,060 total nodes

超时

如果 GitHub 处理 API 请求的时间超过 10 秒,GitHub 将终止该请求并返回超时响应以及“我们未能及时响应您的请求”的提示信息。

GitHub 保留更改超时时间窗口的权利,以保障 API 的速度和可靠性。

您可以在githubstatus.com 查看 GraphQL API 的状态,以判断超时是否由 API 本身的问题导致。您也可以尝试简化请求或稍后再试。例如,如果一次请求中请求了大量对象,可尝试将对象拆分为多个查询请求。

如果您的任意 API 请求出现超时,将在接下来的一小时内从您的主要速率限制中额外扣除点数,以保护 API 的速度和可靠性。

其他资源限制

为保护 API 的速度和可靠性,GitHub 还实施了其他资源限制。如果您的 GraphQL 查询消耗了过多资源,GitHub 将终止请求并返回部分结果,同时返回资源限制已超出的错误信息。

可能超出资源限制的查询示例

  • 在单个查询中请求数千个对象或深度嵌套的关系。
  • 在多个连接中同时使用大的 firstlast 参数。
  • 为每个对象获取大量详细信息,例如每个仓库的所有评论、响应和相关 issue。

查询优化策略

  • 限制对象数量:对 firstlast 参数使用更小的值,并通过分页获取结果。
  • 降低查询深度:除非必要,避免请求深度嵌套的对象。
  • 过滤结果:使用参数过滤数据,仅返回所需内容。
  • 拆分大查询:将复杂查询拆分为多个更简洁的查询。
  • 仅请求所需字段:只选取需要的字段,而不是请求所有可用字段。

遵循这些策略,您可以降低触发资源限制的概率,并提升 API 请求的性能与可靠性。

© . This site is unofficial and not affiliated with GitHub, Inc.