# GraphQL API のレート制限とクエリ制限

GitHub GraphQL API には、GitHubのサーバーに対する過剰または不正な呼び出しから保護するための制限があります。

## プライマリ レート制限

GraphQL API は、各クエリにポイントを割り当て、特定の時間内に使用できるポイントを制限します。 この制限は、不正使用やサービス拒否攻撃を防ぐのに役立ち、すべてのユーザーが API を使用できるようにします。

REST API には、個別のプライマリ レート制限もあります。 詳しくは、「[REST API のレート制限](/ja/rest/using-the-rest-api/rate-limits-for-the-rest-api)」をご覧ください。

一般に、認証の方法に基づいて GraphQL API のプライマリ レート制限を計算できます。

* *ユーザーの場合*: 1 ユーザーごとに 1 時間あたり 5,000 ポイント。 これには、 personal access token で行われた要求と、アプリを承認したユーザーに代わって GitHub App または OAuth app によって行われた要求が含まれます。
  GitHub App組織が所有するGitHub Enterprise Cloudによってユーザーに代わって行われた要求のレート制限は、1 時間あたり 10,000 ポイントと高くなります。 同様に、OAuth app組織によって所有または承認されたGitHub Enterprise Cloudによってユーザーに代わって行われた要求は、GitHub Enterprise Cloud組織のメンバーである場合、1 時間あたり 10,000 ポイントという高いレート制限があります。
* \_
  GitHub App組織GitHub Enterprise Cloud企業以外の\_ インストールあたり 1 時間あたり 5,000 ポイント。 20 以上のリポジトリを持つインストールでは、リポジトリごとにⅠ時間あたり 50 ポイントが追加されます。 ユーザー数が 20 人を超える組織のインストールでは、ユーザーごとに 1 時間あたり別の 50 ポイントを受け取ります。 レート制限は、1 時間あたり 12,500 ポイントを超えて増やすことはできません。 ユーザー アクセストークン（インストール アクセストークンではなく）のレート制限は、ユーザーのプライマリ レート制限によって決まります。
* \_
  GitHub App組織GitHub Enterprise Cloudまたは企業での\_ インストールあたり 1 時間あたり 10,000 ポイント。 ユーザー アクセストークン（インストール アクセストークンではなく）のレート制限は、ユーザーのプライマリ レート制限によって決まります。
* \_
  OAuth appsの場合\_: 1 時間あたり 5,000 ポイント、アプリがGitHub Enterprise Cloud組織によって所有されている場合は 1 時間あたり 10,000 ポイント。 これは、アプリがクライアント ID とクライアント シークレットを使用してパブリック データを要求する場合にのみ適用されます。
  OAuth appによって生成される OAuth アクセス トークンのレート制限は、ユーザーのプライマリ レート制限によって決まります。
* \_
  `GITHUB_TOKEN` ワークフローのGitHub Actionsの場合\_: リポジトリあたり 1 時間あたり 1,000 ポイント。 GitHub.com のエンタープライズ アカウントに属するリソースに対する要求の場合、制限はリポジトリあたり 1 時間あたり 15,000 ポイントです。

次のセクションで説明するように、クエリのポイント値をチェックしたり、予想されるポイント値を計算したりすることができます。 ポイントとレート制限を計算するための数式は、変更される可能性があります。

### プライマリ レート制限の状態のチェック

各応答で送信されるヘッダーを使用して、プライマリ レート制限の現在の状態を判断できます。

| ヘッダー名                   | 説明                                                     |
| ----------------------- | ------------------------------------------------------ |
| `x-ratelimit-limit`     | 1 時間あたりで使用できるポイントの数の上限                                 |
| `x-ratelimit-remaining` | 現在のレート制限ウィンドウ内の残っているポイントの数                             |
| `x-ratelimit-used`      | 現在のレート制限ウィンドウ内の使用したポイントの数                              |
| `x-ratelimit-reset`     | 現在のレート制限ウィンドウが UTC エポック秒単位でリセットされる時刻。                  |
| `x-ratelimit-resource`  | 要求のカウント対象のレート制限リソース。 GraphQL 要求の場合、これは常に `graphql` です。 |

`rateLimit` オブジェクトのクエリを実行して、レート制限をチェックすることもできます。 可能な場合は、API のクエリを実行してレート制限をチェックするのではなく、レート制限応答ヘッダーを使用する必要があります。

```graphql
query {
  viewer {
    login
  }
  rateLimit {
    limit
    remaining
    used
    resetAt
  }
}
```

| フィールド       | 説明                                    |
| ----------- | ------------------------------------- |
| `limit`     | 1 時間あたりで使用できるポイントの数の上限                |
| `remaining` | 現在のレート制限ウィンドウ内の残っているポイントの数            |
| `used`      | 現在のレート制限ウィンドウ内の使用したポイントの数             |
| `resetAt`   | 現在のレート制限ウィンドウが UTC エポック秒単位でリセットされる時刻。 |

### クエリのポイント値を返す

`cost` オブジェクトの `rateLimit` フィールドに対してクエリを実行すると、クエリのポイント値を返すことができます。

```graphql
query {
  viewer {
    login
  }
  rateLimit {
    cost
  }
}
```

### クエリのポイント値の予測

クエリを作成する前に、クエリのポイント値を大まかに計算することもできます。

1. 呼び出し中のそれぞれのユニークなコネクションを満たすために必要なリクエスト数を加算していきます。 すべての要求が `first` または `last` 引数の制限に達するとします。
2. その数字を **100** で除算し、結果を最も近い整数に丸めて最終的な集計ポイント値を取得します。 このステップは、大きな数値を正規化します。

> \[!NOTE]
> GraphQL API の呼び出しの最小ポイント値は **1** です。

以下は、クエリとスコアの計算の例です。

```graphql
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 では Issue のリストを取得するために **100** 個のリポジトリそれぞれに接続する必要があります。 したがって、課題に対するリクエストは**100**です。
* 60 個のラベルが返されますが、API ではラベルのリストを取得するために潜在的に合計 **5,000** 個の Issue のそれぞれに接続する必要があります。 したがって、ラベルの要求 = **5,000** です
* 合計 = **5,101** です

100 で除算して丸めると、最終的なクエリのスコアは **51** になります。

## セカンダリレート制限

プライマリ レート制限に加えて、GitHub では、乱用を防ぎ、すべてのユーザーが API を使用できるように、セカンダリ レート制限が適用されます。

次の場合、セカンダリ レート制限が発生する可能性があります。

* *同時実行要求が多すぎます。* 同時要求は 100 個以下です。 この制限は、REST API と GraphQL API 全体で共有されます。
* *1 分あたりの 1 つのエンドポイントに対する要求が多すぎます。* REST API エンドポイントには 1 分あたり 900 ポイント以下、GraphQL API エンドポイントには 1 分あたり 2,000 ポイント以下を使用できます。 ポイントの詳細については、「[セカンダリ レート制限のポイントの計算](#calculating-points-for-the-secondary-rate-limit)」を参照してください。
* *1 分あたりの要求が多すぎます。* リアルタイムの 60 秒あたりの CPU 時間は 90 秒以下です。 GraphQL API、この CPU 時間の 60 秒以下を使用できます。 API 要求の合計応答時間を測定することで、CPU 時間を大まかに見積もることができます。
* *短時間に過剰なコンピューティングリソースを消費するリクエストを大量に送信します。*
* ```
            _短時間のうちに GitHub 上で過度に多くのコンテンツを作成します。_ 一般に、1 分あたり 80 件以下のコンテンツ生成要求と、1 時間あたり 500 件を超えるコンテンツ生成要求は許可されません。 一部のエンドポイントでは、コンテンツ作成の制限が低くなります。 コンテンツ作成の制限には、GitHub ウェブ インターフェイスに対して実行されるアクションと、REST API と GraphQL API を介して実行されるアクションが含まれます。
  ```
* *短時間で OAuth アクセス トークン要求が多すぎます。* GitHub Apps と OAuth apps に対して、1 時間あたり 2,000 個以下の OAuth アクセス トークン要求が許可されません。

これらのセカンダリ レート制限は、予告なしに変更される場合があります。 また、未公開の理由により、セカンダリ レート制限が発生する可能性もあります。

### セカンダリ レート制限のポイントの計算

一部のセカンダリ レート制限は、要求のポイント値によって決まります。 GraphQL 要求の場合、これらのポイント値は、プライマリ レート制限のポイント値の計算とは別です。

| 要求                                                  | ポイント |
| --------------------------------------------------- | ---- |
| 変更のない GraphQL 要求                                    | 1    |
| 変更を含む GraphQL 要求                                    | 5    |
| ほとんどの REST API `GET`、 `HEAD`、および `OPTIONS` 要求       | 1    |
| ほとんどの REST API `POST`、`PATCH`、`PUT` または `DELETE` 要求 | 5    |

一部の REST API エンドポイントでは、パブリックに共有されていないポイント コストが異なります。

## レート制限の超過

プライマリ レート制限を超えた場合、応答の状態は引き続き `200` になりますが、エラー メッセージが表示され、`x-ratelimit-remaining` ヘッダーの値は `0` になります。 指定された時間になるまで`x-ratelimit-reset`ヘッダーが示す時刻までリクエストを再試行しないでください。

セカンダリ レート制限を超えた場合は、応答の状態は `200` または `403` になり、セカンダリ レート制限に達したことを示すエラー メッセージが表示されます。
`retry-after` 応答ヘッダーが存在する場合は、その秒数が経過するまで要求を再試行しないでください。
`x-ratelimit-remaining` ヘッダーが `0`、`x-ratelimit-reset` ヘッダーで指定された時刻 (UTC エポック秒数) まで要求を再試行しないでください。 それ以外の場合は、少なくとも 1 分間待ってから再試行します。 要求が二次レート制限により継続して失敗する場合は、再試行の間は指数関数的に増加する時間を待ち、特定の回数の再試行の後にエラーを発生させます。

レート制限中に要求を続けると、統合を禁止する可能性があります。

## レート制限を超えないようにする

レート制限を超えないようにするには、変更要求間で少なくとも 1 秒一時停止し、同時要求を回避する必要があります。

API でデータをポーリングする代わりに、Webhook イベントをサブスクライブする必要もあります。 詳しくは、「[Webhook ドキュメント](/ja/webhooks)」をご覧ください。

API 要求を表示するために、監査ログをストリーミングすることもできます。 これは、レート制限を超える統合のトラブルシューティングに役立ちます。 詳しくは、「[企業の監査ログのストリーミング](/ja/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/streaming-the-audit-log-for-your-enterprise)」をご覧ください。

## ノードの制限

[schema](/ja/graphql/guides/introduction-to-graphql#schema) 検証に合格するには、すべての GraphQL API [calls](/ja/graphql/guides/forming-calls-with-graphql) が次の標準を満たしている必要があります。

* クライアントは、任意の`first`に対して、`last` または [](/ja/graphql/guides/introduction-to-graphql#connection) 引数を指定する必要があります。
* `first` と `last` の値は 1 から 100 である必要があります。
* 個々の呼び出しでは、合計 500,000 を超える [nodes](/ja/graphql/guides/introduction-to-graphql#node) を要求することはできません。

### 呼び出し中のノードの計算

以下の2つの例は、呼び出し中の合計ノード数を計算する方法を示しています。

1. 単純なクエリ：

   <pre>query {
     viewer {
       repositories(first: <span class="redbox">50</span>) {

edges {
repository:node {
name

issues(first: <span class="greenbox">10</span>) {
totalCount
edges {
node {
title
bodyHTML
}
}
}
}
}
}
}
}</pre>

計算:

   <pre><span class="redbox">50</span>         = 50 repositories
    +
   <span class="redbox">50</span> x <span class="greenbox">10</span>  = 500 repository issues

= 550 total nodes</pre>

1. 複雑なクエリ：

   <pre>query {
     viewer {
       repositories(first: <span class="redbox">50</span>) {

edges {
repository:node {
name

pullRequests(first: <span class="greenbox">20</span>) {
edges {
pullRequest:node {
title

comments(first: <span class="bluebox">10</span>) {
edges {
comment:node {
bodyHTML
}
}
}
}
}
}

issues(first: <span class="greenbox">20</span>) {
totalCount
edges {
issue:node {
title
bodyHTML

comments(first: <span class="bluebox">10</span>) {
edges {
comment:node {
bodyHTML
}
}
}
}
}
}
}
}
}

```
   followers(first: <span class="bluebox">10</span>) {
```

edges {
follower:node {
login
}
}
}
}
}</code></pre>

計算:

   <pre><span class="redbox">50</span>              = 50 repositories
    +
   <span class="redbox">50</span> x <span class="greenbox">20</span>       = 1,000 pullRequests
    +
   <span class="redbox">50</span> x <span class="greenbox">20</span> x <span class="bluebox">10</span> = 10,000 pullRequest comments
    +
   <span class="redbox">50</span> x <span class="greenbox">20</span>       = 1,000 issues
    +
   <span class="redbox">50</span> x <span class="greenbox">20</span> x <span class="bluebox">10</span> = 10,000 issue comments
    +
   <span class="bluebox">10</span>              = 10 followers

= 22,060 total nodes</pre>

## タイムアウト

GitHub API 要求の処理に 10 秒以上かかる場合、GitHubは要求を終了し、タイムアウト応答と"要求に時間内に応答できませんでした" というメッセージを受け取ります。

このような場合は、 `502` または `504` 状態コードを受け取る可能性があります。 どちらの状態コードも、要求がタイムアウトしたことを示しています。

GitHub は、API の速度と信頼性を保護するためにタイムアウト 期間を変更する権利を留保します。

[githubstatus.com](https://www.githubstatus.com/) で GraphQL API の状態をチェックして、タイムアウトの原因が API の問題かどうかを判断できます。 また、要求を簡略化したり、後で要求を試したりすることもできます。 クエリのパフォーマンス向上に関するヒントについては、「 [クエリの最適化戦略](#query-optimization-strategies)」を参照してください。

いずれかの API 要求でタイムアウトが発生した場合、API の速度と信頼性を保護するために、その後の 1 時間、プライマリ レート制限から追加のポイントが差し引かれます。

## その他のリソース制限

API の速度と信頼性を保護するために、 GitHub では他のリソース制限も適用されます。 GraphQL クエリで消費されるリソースが多すぎる場合、 GitHub は要求を終了し、リソースの制限を超えたことを示すエラーと共に部分的な結果を返します。

**リソース制限を超える可能性があるクエリの例:**

* 何千ものオブジェクト、または入れ子構造が深いリレーションシップを 1 つのクエリで要求する。
* 大きな `first` または `last` 引数を複数の接続で同時に使う。
* 各オブジェクトの詳細な情報として、すべてのリポジトリにあるコメント、反応、関連する issue を取得する。

## クエリの最適化戦略

* **オブジェクト数を制限する**: `first` または `last` 引数に小さい値を使い、結果を複数ページに分割します。
* **クエリの深さを減らす**: 必要でない場合は、入れ子構造が深いオブジェクトを要求しないようにします。
* **結果をフィルター処理する**: 引数を使ってデータをフィルター処理し、必要なもののみを返します。
* **大きなクエリを分割する**: 複雑なクエリを複数の単純なクエリに分割します。
* **必須フィールドのみを要求する**: 使用できるすべてのフィールドを要求するのではなく、必要なフィールドのみを選びます。

このような戦略に従うことで、リソース制限に達する可能性を減らし、API 要求のパフォーマンスと信頼性を向上させることができます。