Guide

メールAPI レート制限:全プロバイダー比較

Gmail、Microsoft Graph、Yahoo、Exchange EWS、iCloud はそれぞれ異なるレート制限、クォータシステム、スロットリングルールを適用しています。本ガイドでは各プロバイダーの制限を 1 つの表で比較し、超過時に返される SMTP エラーコードを整理し、バックオフロジックを自分で書かずに再試行を処理する方法を解説します。

Written by Aaron de Mello Senior Engineering Manager

VerifiedCLI 3.1.11 · Gmail, Outlook · last tested May 21, 2026

コマンドリファレンス: nylas email list nylas email send nylas email search

Gmail API のレート制限とは?

Gmail API のレート制限は、生のリクエスト数ではなくクォータユニットで測定されます。Gmail API のメソッドごとに消費ユニット数が異なり、各ユーザーにはデフォルトで毎秒 250 ユニットが割り当てられます。messages.list の呼び出しは 5 ユニット、messages.get は 5 ユニット、messages.send は 100 ユニットを消費します。つまり、送信はユーザーあたり毎秒最大 2 通までですが、一覧取得は毎秒 50 ページまで可能です。

Google の Gmail API クォータドキュメントによると、ユーザーあたりのレート制限は 2026 年 5 月 1 日に 250 ユニット/ユーザー/秒へ更新されました(以前は日次クォータのみの追跡でした)。プロジェクトあたりの日次上限は 10 億クォータユニットです。いずれかを超過すると、Retry-After ヘッダー付きの HTTP 429 が返されます。

Gmail API メソッドクォータコスト最大呼び出し数/秒(ユーザーあたり)
messages.list5 ユニット50
messages.get5 ユニット50
messages.send100 ユニット2
messages.modify5 ユニット50
messages.trash10 ユニット25
history.list2 ユニット125
messages.batchGet各 5 ユニット50(バッチ内のメッセージあたり)

このクォータユニット方式では、messages.list を呼んでから各結果に messages.get を実行する素朴な同期ループは、メッセージあたり 10 ユニットを消費します。1,000 件のメッセージの同期には合計 10,000 ユニットかかり、1 ユーザーが 40 秒で使い切る量です。バッチエンドポイントは往復のオーバーヘッドを減らしますが、メッセージあたりのユニットコストは変わりません。CLI はこれらの呼び出しを内部でバッチ化し、Retry-After ヘッダーを尊重するため、nylas email list --limit 1000 の 1 コマンドで追加コードなしにページネーションとスロットリングを処理できます。

# List up to 200 Gmail messages — the CLI handles pagination and rate limits
nylas email list --limit 200 --json

Microsoft Graph のメールレート制限とは?

Microsoft Graph は、アプリ×メールボックスあたり 10 分間に 10,000 リクエストのスロットリングを適用します。これはメールボックスあたり毎秒およそ 16 リクエストに相当します。制限を超えると、Graph は待機すべき秒数を示す Retry-After ヘッダー付きの HTTP 429 を返します。Gmail と異なり、Graph はユニットコスト方式を採用しておらず、エンドポイントの複雑さに関係なくすべてのリクエストが 1 としてカウントされます。

Microsoft の Graph API スロットリングドキュメントによると、10 分あたり 10,000 件の制限は Outlook のメール、カレンダー、連絡先エンドポイントに適用されます。テナント全体の制限はそれより高く設定されています(非公開、サービス依存)。$batch エンドポイント経由のバッチリクエストはスロットリング上 1 リクエストとしてカウントされますが、1 バッチあたり 20 オペレーションまでに制限されています。各メッセージに個別の GET が必要な場合、メール同期の実質的な上限は 10 分間に約 3,200 件です。

Graph はさらに、Microsoft 365 ビジネスアカウントには 1 日あたり 10,000 受信者、Outlook.com コンシューマーアカウントには 1 日あたり 300 通の送信制限を課しています。重要なのはメッセージ数ではなく受信者数です。50 人の受信者への 1 通のメッセージは、日次制限に対して 50 としてカウントされます。

CLI はこれらの制限を 1 つのコマンドの背後に抽象化します。Outlook メールボックスに対して nylas email send を実行すると、429 レスポンスは自動的に処理され、Retry-After ヘッダーで指定された遅延で再試行されます。

# Send an email through Outlook — retries on 429 are handled by the CLI
nylas email send --to "recipient@example.com" --subject "Quarterly report" --body "Attached."

メールプロバイダー間でレート制限はどう違う?

レート制限の適用方法は、主要 5 メールプロバイダーの間で大きく異なります。Gmail はメソッドごとのコストを持つクォータユニットを使用します。Microsoft Graph はフラットなリクエスト数を使用します。Yahoo と iCloud は非公開の IMAP レベルの接続制限を適用しています。Exchange EWS は同時リクエスト数によるスロットリングを使用します。以下の表は、自動化されたメールワークフローで最も重要となる数値 — 毎秒リクエスト数、1 日あたりのメッセージ数、添付ファイルサイズ上限 — を示しています。

プロバイダーレート制限モデル実効読み取り/秒送信制限/日最大添付サイズ
Gmail APIクォータユニット(250/ユーザー/秒)~502,000 通25 MB
Microsoft Graphフラットなリクエスト数(10,000/10 分)~1610,000 受信者150 MB
Yahoo IMAP接続ベース(非公開)~5-10500 通25 MB
Exchange EWS同時リクエスト(最大 27)~2710,000 受信者35 MB(デフォルト)
iCloud IMAP接続ベース(非公開)~51,000 通20 MB

「実効読み取り/秒」の列は、プロバイダーのドキュメントに記載された理論上の最大値ではなく、list + get の同期パターンにおける現実的なスループットを反映しています。Gmail のユニット方式は読み取り中心のワークロードに最も寛容です。Graph のフラットカウントモデルはシンプルですが、一括同期にはより制約が大きくなります。Yahoo と iCloud は正確な数値を公開していないため、上記の推定値は利用年数の異なるアカウントに対する CLI での実測テストに基づいています。

レート制限を示す SMTP エラーコードは?

SMTP のレート制限エラーは 2 つのカテゴリーに分かれます:REST API からの HTTP ステータスコードと、メールサーバーからの SMTP 拡張ステータスコードです。HTTP 429「Too Many Requests」レスポンスは Gmail API と Microsoft Graph からの標準的なシグナルです。SMTP サーバーは 4.7.x 系の拡張ステータスコードを使用します。どのコードに直面しているかによって、すぐに再試行すべきか、数時間待つべきかが決まります。

コードプロバイダー意味再試行戦略
HTTP 429Gmail、Graphクォータまたはリクエスト制限の超過Retry-After ヘッダーの値だけ待機
4.7.28Gmail SMTP直近 24 時間のローリングウィンドウでの送信過多24 時間ウィンドウのリセットまで待機
4.7.0Yahoo SMTP接続または送信の一時的なレート制限指数バックオフ、ベース 30 秒
5.7.3Exchange / Microsoft 365日次受信者制限の超過翌暦日まで再試行不可
421iCloud SMTP同時接続数の超過接続数を減らし、60 秒後に再試行
HTTP 503Graphサービスの一時的な利用不可(スロットリング起因が多い)指数バックオフ、ベース 5 秒

4xx と 5xx の拡張ステータスコードの違いは重要です。Gmail の 4.7.28 は一時的で、時間とともに自然に解消します。Exchange の 5.7.3 は日次のハードキャップに達したことを意味します。Google の Workspace 送信制限ドキュメントによると、無料の Gmail アカウントは 1 日あたり 500 通、Google Workspace アカウントは 2,000 通に制限されています。CLI はこれらのエラーコードを解析し、再試行の挙動を適切に調整します。

レート制限に達した後はどう再試行すべき?

ジッター付き指数バックオフは、メール API のレート制限に対する標準的な再試行戦略です。このパターンでは、失敗のたびに待機時間を 2 倍にし(1 秒、2 秒、4 秒、8 秒)、複数のクライアントが同時に同じ制限に達した際のサンダリングハード問題を防ぐために 0〜1 秒のランダムなジッターを加えます。ジッターがないと、並列ワーカーからの同期した再試行が積み重なり、スロットリング期間が延びてしまいます。

Google の API エラー処理ドキュメントによると、推奨される最大再試行回数は 5 回で、バックオフ間隔の上限は 32 秒です。Microsoft の Graph ドキュメントは、独自の遅延を計算するのではなく Retry-After ヘッダーの値を正確に守ることを推奨しています。実際には、Gmail の Retry-After 値は通常 1〜60 秒、Graph はスロットリングの深刻度に応じて 5〜300 秒を返します。

Gmail や Graph の API を直接呼び出す場合、このループを自分で実装する必要があります。以下の Python スニペットはジッター付きの最小実装を示しています。再試行のたびにベース遅延を 2 倍にし、最大 1 秒のランダムなジッターを加えます。5 回失敗すると、関数は無限ループせず例外を送出します。

import time, random, requests

def call_with_backoff(url, headers, max_retries=5):
    delay = 1
    for attempt in range(max_retries):
        resp = requests.get(url, headers=headers)
        if resp.status_code != 429:
            return resp
        retry_after = int(resp.headers.get("Retry-After", delay))
        jitter = random.uniform(0, 1)
        wait = retry_after + jitter
        print(f"Rate limited. Retry {attempt + 1}/{max_retries} in {wait:.1f}s")
        time.sleep(wait)
        delay = min(delay * 2, 32)
    raise Exception("Max retries exceeded")

CLI は内部でレート制限をどう処理する?

Nylas CLI はレート制限をプラットフォーム層で処理するため、再試行ロジックを自分で書く必要はありません。背後の Nylas API が Gmail、Graph、その他の接続済みプロバイダーから 429 を受け取ると、自動的に指数バックオフで再試行します。CLI はこの挙動を継承します。nylas email list --limit 500 の 1 コマンドが裏で数十回のページネーション API 呼び出しを発生させることもありますが、そのすべてがプロバイダーのスロットリングシグナルを尊重し、エラーをユーザーに露出させません。

このプラットフォームは、Gmail、Outlook、Exchange、Yahoo、iCloud、IMAP プロバイダー全体で月間 12 億件以上の API 呼び出しを処理しています。この規模により、再試行ロジックは上の表にあるすべてのレート制限パターンに対してテスト済みです。ここで説明したプロバイダー側の挙動は、ドキュメント化されたプロバイダーの動作と Gmail および Outlook での当社のテストに基づいています。Yahoo、iCloud、EWS に関するプロバイダー固有の前提は、デプロイ前にローカルで検証してください。

レート制限ヘッダーを含む生の API レスポンスを確認するには、任意のコマンドに --json を追加します。JSON 出力には、プロバイダーのレスポンスヘッダーを表すメタデータフィールドが含まれます。これは複数の CLI コマンドを連結するスクリプトのデバッグに役立ちます。429 が発生したか、再試行がどれだけ待機したかを検査できるためです。

# Fetch 500 messages with full JSON output including response metadata
nylas email list --limit 500 --json | jq '.[0:3]'

メールボックス全体の同期や 2,000 通のキャンペーン送信のような一括処理では、CLI はリクエストを内部でキューイングし、プロバイダーの制限内に収めます。10,000 件のメッセージを含む Gmail 受信トレイの完全同期は、クォータが許容する持続レートで約 3 分かかります。制限を完全に無視できる場合の約 40 秒と比較してください。

プロバイダーごとのバッチ操作の制限は?

バッチ操作を使うと、複数の API 呼び出しを 1 つの HTTP リクエストにまとめられ、往復のオーバーヘッドを減らし、場合によってはリクエスト単位のスロットリングを回避できます。Gmail は 1 バッチあたり最大 100 件の呼び出しをサポートし、Microsoft Graph はバッチを 20 オペレーションまでに制限しています。Exchange EWS には正式なバッチエンドポイントはありませんが、ページング付きの FindItem によるグループ操作をサポートしています。

Google のバッチリクエストドキュメントによると、Gmail のバッチ内の各オペレーションは、それぞれのクォータユニットを満額消費します。100 件の messages.get 呼び出しのバッチは 500 ユニットを消費し、100 回の個別呼び出しと同じです。利点はレイテンシーであり、クォータの節約ではありません。Microsoft の $batch エンドポイントは異なります:バッチ自体は 10 分あたり 10,000 件のスロットリングに対して 1 リクエストとしてカウントされますが、内部の各オペレーションは独立して実行され、個別に失敗する可能性があります。

プロバイダーバッチあたり最大オペレーション数クォータ節約スロットリングのカウント方法
Gmail API100なし(オペレーションごとに満額のユニットコスト)各オペレーションを個別にカウント
Microsoft Graph20あり(スロットリング上 1 リクエスト)バッチを 1 リクエストとしてカウント
Exchange EWS正式なバッチなしN/A各リクエストを個別にカウント
Yahoo IMAPN/A(IMAP プロトコル)N/A接続レベルのスロットリング
iCloud IMAPN/A(IMAP プロトコル)N/A接続レベルのスロットリング

CLI はプロバイダーが対応している場合にバッチ処理を使用します。Gmail では、ページネーション中のレイテンシーを減らすために messages.get 呼び出しを 100 件のバッチにまとめます。Graph では、スロットリング上の利点を最大化するために 1 つの $batch リクエストに最大 20 オペレーションを詰め込みます。設定は不要で、nylas email list の背後で自動的に行われます。

レート制限の使用状況はどう監視する?

Gmail のクォータ使用状況は、Google Cloud Console の APIs & Services > Gmail API > Quotas で確認でき、メソッド別のリアルタイムなユニット消費が見られます。Microsoft Graph は Azure ポータルの App Registrations > 対象アプリ > Performance で使用状況データを提供しています。どちらのダッシュボードも 5 分ごとに更新され、30 日分の履歴を表示します。スロットリングイベントのパターンを発見するには十分です。

CLI ベースのワークフローでは、任意のコマンドに --json を追加し、出力を jq にパイプして結果数をカウントし、API 呼び出し量を見積もります。以下のコマンドは 100 件のメッセージを一覧取得してカウントし、消費した Gmail クォータユニットの概算を計算します。messages.list 1 ページ(1 ページ 100 件)あたり 5 ユニット、メッセージごとの messages.get あたり 5 ユニットとすると、100 件でおよそ 505 クォータユニットかかります。

# Count messages returned and estimate Gmail quota cost
COUNT=$(nylas email list --limit 100 --json | jq 'length')
echo "$COUNT messages fetched"
echo "Estimated quota cost: $((5 + COUNT * 5)) units"

定期的な同期スクリプトを実行している場合は、実行ごとに件数とタイムスタンプをログに残してください。5 分ごとに同期して 1 回あたり 200 件を取得する cron ジョブは、1 サイクルあたり約 1,005 ユニット、1 日あたりおよそ 289,440 ユニットを消費します。これは日次のプロジェクト上限 10 億ユニットには十分収まりますが、数千ユーザー規模に拡大する場合は追跡する価値があります。

次のステップ