Guide

이메일 API 속도 제한: 프로바이더 비교

Gmail, Microsoft Graph, Yahoo, Exchange EWS, iCloud는 각기 다른 속도 제한, 할당량 시스템, 스로틀링 규칙을 적용합니다. 이 가이드는 이를 하나의 표로 비교하고, 제한 초과 시 만나게 되는 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 속도 제한은 원시 요청 수가 아닌 할당량 단위(quota unit)로 측정됩니다. 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단위가 들고, 이는 단일 사용자가 40초 만에 소진할 수 있는 양입니다. 배치 엔드포인트는 왕복 오버헤드를 줄이지만 메시지당 단위 비용은 바꾸지 못합니다. CLI는 이러한 호출을 내부적으로 배치 처리하고 Retry-After 헤더를 준수하므로, nylas email list --limit 1000 명령 하나로 추가 코드 없이 페이지네이션과 스로틀링을 처리합니다.

# 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개 요청으로 계산되지만 배치당 20개 작업으로 제한됩니다. 각 메시지에 별도의 GET이 필요한 경우 메일 동기화의 실질적인 상한은 10분당 약 3,200개 메시지입니다.

Graph는 또한 Microsoft 365 비즈니스 계정에는 하루 10,000명의 수신자, Outlook.com 소비자 계정에는 하루 300개 메시지라는 전송 제한을 적용합니다. 중요한 것은 메시지 수가 아니라 수신자 수입니다. 수신자 50명에게 보낸 메시지 하나가 일일 한도에서 50으로 계산됩니다.

CLI는 이러한 제한을 단일 명령 뒤로 추상화합니다. 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는 동시 요청 스로틀링을 사용합니다. 아래 표는 자동화된 이메일 워크플로에서 가장 중요한 수치인 초당 요청 수, 일일 메시지 수, 첨부 파일 크기 상한을 보여줍니다.

프로바이더속도 제한 모델실효 읽기/초일일 전송 제한최대 첨부 파일
Gmail API할당량 단위 (250/사용자/초)~50메시지 2,000개25 MB
Microsoft Graph고정 요청 수 (10,000/10분)~16수신자 10,000명150 MB
Yahoo IMAP연결 기반 (문서화되지 않음)~5-10메시지 500개25 MB
Exchange EWS동시 요청 (최대 27개)~27수신자 10,000명35 MB (기본값)
iCloud IMAP연결 기반 (문서화되지 않음)~5메시지 1,000개20 MB

"실효 읽기/초" 열은 프로바이더 문서상의 이론적 최댓값이 아니라 list + get 동기화 패턴의 현실적인 처리량을 반영합니다. Gmail의 단위 시스템은 읽기 중심 워크로드에 가장 관대합니다. Graph의 고정 카운트 모델은 더 단순하지만 대량 동기화에는 더 제한적입니다. Yahoo와 iCloud는 정확한 수치를 공개하지 않으므로, 위 추정치는 다양한 연령의 계정에서 CLI로 수행한 실측 테스트에서 얻은 것입니다.

속도 제한을 나타내는 SMTP 오류 코드는?

SMTP 속도 제한 오류는 두 범주로 나뉩니다. 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 계정은 하루 500개 메시지로 제한되고 Google Workspace 계정은 2,000개까지 가능합니다. CLI는 이러한 오류 코드를 파싱하여 재시도 동작을 그에 맞게 조정합니다.

속도 제한에 걸린 후 어떻게 재시도해야 하나요?

지터(jitter)를 더한 지수 백오프는 이메일 API 속도 제한에 대한 표준 재시도 전략입니다. 이 패턴은 시도가 실패할 때마다 대기 시간을 두 배로 늘리고(1초, 2초, 4초, 8초), 여러 클라이언트가 동시에 같은 제한에 걸렸을 때 발생하는 thundering-herd 문제를 막기 위해 0~1초의 무작위 지터를 더합니다. 지터가 없으면 병렬 워커들의 동기화된 재시도가 한꺼번에 몰려 스로틀 윈도우가 길어집니다.

Google의 API 오류 처리 문서에 따르면, 권장 최대 재시도 횟수는 5회이며 백오프 간격 상한은 32초입니다. Microsoft의 Graph 문서는 자체적으로 지연을 계산하지 말고 Retry-After 헤더 값을 정확히 따를 것을 권장합니다. 실제로 Gmail의 Retry-After 값은 보통 1~60초이고, Graph는 스로틀 심각도에 따라 5~300초를 반환합니다.

Gmail이나 Graph API를 직접 호출한다면 이 루프를 직접 구현해야 합니다. 아래 Python 스니펫은 지터를 포함한 최소 구현입니다. 재시도할 때마다 기본 지연이 두 배가 되고 최대 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 명령 하나가 내부적으로 수십 개의 페이지네이션 API 호출을 일으킬 수 있으며, 모든 호출이 오류를 사용자에게 노출하지 않고 프로바이더의 스로틀 신호를 준수합니다.

이 플랫폼은 Gmail, Outlook, Exchange, Yahoo, iCloud, IMAP 프로바이더 전반에서 매월 12억 건 이상의 API 호출을 처리합니다. 이 정도 볼륨이라면 재시도 로직이 위 표의 모든 속도 제한 패턴에 대해 검증되었다는 뜻입니다. 여기서 설명한 프로바이더 측 동작은 문서화된 프로바이더 동작과 Gmail 및 Outlook에 대한 자체 테스트를 기반으로 합니다. Yahoo, iCloud, EWS에 대한 프로바이더별 가정은 배포 전에 로컬에서 검증하세요.

속도 제한 헤더를 포함한 원시 API 응답을 보려면 아무 명령에나 --json을 추가하세요. JSON 출력에는 프로바이더의 응답 헤더를 보여주는 메타데이터 필드가 포함됩니다. 429가 발생했는지, 재시도가 얼마나 기다렸는지 확인할 수 있으므로 여러 CLI 명령을 연결하는 스크립트를 디버깅할 때 유용합니다.

# 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 호출을 하나의 HTTP 요청으로 묶어 왕복 오버헤드를 줄이고, 경우에 따라 요청별 스로틀을 우회할 수 있습니다. Gmail은 배치당 최대 100개 호출의 배치 요청을 지원하고, Microsoft Graph는 배치를 20개 작업으로 제한합니다. Exchange EWS에는 공식 배치 엔드포인트가 없지만 페이징을 사용하는 FindItem을 통한 그룹 작업을 지원합니다.

Google의 배치 요청 문서에 따르면, Gmail 배치 내부의 각 작업은 여전히 전체 할당량 단위를 소비합니다. messages.get 호출 100개로 이루어진 배치는 개별 호출 100개와 동일한 500단위가 듭니다. 이점은 할당량 절약이 아니라 지연 시간입니다. Microsoft의 $batch 엔드포인트는 다릅니다. 배치 자체는 10분당 10,000개 스로틀에서 단일 요청으로 계산되지만, 내부의 각 작업은 독립적으로 실행되며 개별적으로 실패할 수 있습니다.

프로바이더배치당 최대 작업 수할당량 절약?스로틀 계산 방식
Gmail API100아니요 (작업당 전체 단위 비용)각 작업 개별 계산
Microsoft Graph20예 (스로틀에서 1개 요청)배치가 1개 요청으로 계산
Exchange EWS공식 배치 없음해당 없음각 요청 개별 계산
Yahoo IMAP해당 없음 (IMAP 프로토콜)해당 없음연결 레벨 스로틀
iCloud IMAP해당 없음 (IMAP 프로토콜)해당 없음연결 레벨 스로틀

CLI는 프로바이더가 지원하는 곳에서 배치를 사용합니다. Gmail에서는 페이지네이션 중 지연 시간을 줄이기 위해 messages.get 호출을 100개 단위 배치로 묶습니다. Graph에서는 스로틀 이점을 극대화하기 위해 $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 페이지당 5단위(페이지당 100개 결과)에 메시지마다 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분마다 동기화하며 실행당 200개 메시지를 가져오는 cron 작업은 사이클당 약 1,005단위, 하루 약 289,440단위를 소비합니다. 일일 10억 단위 프로젝트 한도에는 한참 못 미치지만, 수천 명의 사용자로 확장한다면 추적할 가치가 있습니다.

다음 단계