Skip to content

429/용량 오류: 계정 로테이션의 올바른 예상과 모델 용량 고갈의 오해

이 과정을 통해 할 수 있는 것

  • "할당량 부족"과 "상류 속도 제한"을 올바르게 구분하여 오해 방지
  • Antigravity Tools의 자동 로테이션 메커니즘과 예상 동작 이해
  • 429 오류 발생시 빠르게 문제를 찾아내고 구성을 최적화하는 방법 숙지

현재 겪고 있는 문제

  • 429 오류가 반환되면 "모델 용량이 없다"고 오해함
  • 여러 계정을 구성했지만 여전히 자주 429를 만나고, 구성 문제인지 계정 문제인지 알 수 없음
  • 시스템이 언제 자동으로 계정을 전환하는지, 언제 "멈추는지" 확실하지 않음

핵심 원리

429 오류란?

429 Too Many Requests는 HTTP 상태 코드입니다. Antigravity Tools에서 429는 "요청이 너무 잦음"만을 의미하는 것이 아니라, 할당량 고갈, 모델 일시적 과부하 등 "일시적으로 사용할 수 없음"을 나타내는 신호일 수도 있습니다.

프록시는 429 원인 식별을 시도합니다

프록시는 응답 본문에서 error.details[0].reason 또는 error.message를 구문 분석하여 429를 대략적으로 몇 가지 유형으로 분류합니다(실제로는 반환된 결과를 기준으로 함):

프록시 식별 유형일반적인 reason / 단서전형적 특징
할당량 고갈QUOTA_EXHAUSTED / 텍스트에 exhausted, quota 포함할당량이 새로고침될 때까지 기다려야 할 수 있음
속도 제한RATE_LIMIT_EXCEEDED / 텍스트에 per minute, rate limit, too many requests 포함보통 수십 초 수준의 냉각
모델 용량 부족MODEL_CAPACITY_EXHAUSTED / 텍스트에 model_capacity 포함일반적으로 일시적 과부하, 나중에 복구 가능
알 수 없음구문 분석 불가기본 냉각 정책 사용

Antigravity Tools의 자동 처리

단일 요청이 429(및 일부 5xx/과부하 상태)를 만나면 프록시는 일반적으로 서버 측에서 두 가지 작업을 수행합니다:

  1. 냉각 시간 기록: 이 오류를 RateLimitTracker에 기록하여 후속 계정 선택 시 "여전히 냉각 중인" 계정을 능동적으로 피합니다.
  2. 재시시에서 계정 로테이션: Handlers는 단일 요청 내에서 여러 번 시도하며, 재시시에는 force_rotate=true로 설정하여 TokenManager가 다음 사용 가능한 계정을 선택하도록 트리거합니다.

계정 전환 여부를 어떻게 알 수 있나요?

요청 본문이 변경되지 않더라도 응답에는 보통 X-Account-Email(및 X-Mapped-Model)이 포함되어 있으므로 이를 사용하여 "이번 요청에 어떤 계정이 사용되었는지" 확인할 수 있습니다.

429 오류는 언제 발생하나요?

시나리오 1: 단일 계정 요청 속도가 너무 빠름

현상: 단일 계정만 있어도 짧은 시간 내에 대량의 요청을 보내면 429가 트리거됩니다.

원인: 각 계정에는 자체 속도 제한(RPM/TPM)이 있으며 초과하면 속도 제한됩니다.

해결:

  • 계정 수 증가
  • 요청 빈도 낮추기
  • 고정 계정 모드 사용하여 부하 분산(자세한 내용은 "고정 계정 모드" 참조)

시나리오 2: 모든 계정이 동시에 속도 제한됨

현상: 여러 계정이 있지만 모든 계정이 429를 반환합니다.

원인:

  • 계정 총수가 요청 빈도를 지원하기에 충분하지 않음
  • 모든 계정이 거의 동시에 속도 제한/과부하 트리거

해결:

  • 더 많은 계정 추가
  • 스케줄링 모드를 "성능 우선"으로 조정(스티키 세션 및 60초 창 재사 건너뜀)
  • 할당량 보호가 사용 가능한 계정을 잘못 제외했는지 확인

시나리오 3: 계정이 할당량 보호에 의해 오해 판정됨

현상: 특정 계정의 할당량이 충분한데 시스템이 계속해서 건너뜁니다.

원인:

  • 할당량 보호가 활성화되어 있고 임계값이 너무 높게 설정됨
  • 해당 계정의 특정 모델 할당량이 임계값보다 낮음
  • 계정이 수동으로 proxy_disabled로 표시됨

해결:

  • 할당량 보호 설정 확인(Settings → Quota Protection), 사용 강도에 따라 임계값과 모니터링 모델 조정
  • 계정 데이터에서 protected_models 확인, 보호 정책에 의해 건너뛰는지 확인

따라 해보세요

1단계: 429 오류 유형 식별

이유: 다른 유형의 429 오류는 다른 처리 방식이 필요합니다.

Proxy Monitor에서 429 오류의 응답 본문을 보고 두 가지 정보에 중점을 둡니다:

  • 원인: error.details[0].reason(예: RATE_LIMIT_EXCEEDED, QUOTA_EXHAUSTED) 또는 error.message
  • 대기 시간: RetryInfo.retryDelay 또는 details[0].metadata.quotaResetDelay(존재하는 경우)
json
{
  "error": {
    "details": [
      {
        "reason": "RATE_LIMIT_EXCEEDED",
        "metadata": {
          "quotaResetDelay": "42s"
        }
      }
    ]
  }
}

예상 결과:

  • 응답 본문에서 대기 시간(예: RetryInfo.retryDelay 또는 quotaResetDelay)을 찾을 수 있으면 프록시는 보통 짧은 시간 동안 기다린 후 재시도합니다.
  • 대기 시간이 없으면 프록시는 내장 정책에 따라 해당 계정에 "냉각 기간"을 추가하고 재시시에서 즉시 다음 계정으로 전환합니다.

2단계: 계정 스케줄링 구성 확인

이유: 스케줄링 구성은 계정 로테이션 빈도와 우선순위에 직접적인 영향을 미칩니다.

API Proxy 페이지로 이동하여 스케줄링 정책을 확인하세요:

구성 항목설명기본값/권장
Scheduling Mode스케줄링 모드Balance(기본값)
Preferred Account고정 계정 모드선택되지 않음(기본값)

스케줄링 모드 비교:

모드계정 재사용 정책속도 제한 처리적용 시나리오
CacheFirst스티키 세션 및 60초 창 재사 사용 활성화우선 대기, Prompt Caching 적중률 크게 향상대화형/높은 캐시 적중률 필요
Balance스티키 세션 및 60초 창 재사 사용 활성화즉시 대체 계정으로 전환, 성공률과 성능 균형일반 시나리오, 기본값
PerformanceFirst스티키 세션 및 60초 창 재사 건너뜀, 순수 라운드 로빈 모드즉시 전환, 계정 부하 가장 균형고동시성, 무상태 요청

캐시 우선 vs 균형 모드

Prompt Caching를 사용하고 캐시 적중률을 높이려면 CacheFirst를 선택하세요 — 속도 제한 시 즉시 계정 전환 대신 우선 대기합니다. 요청 성공률을 더 중요하게 생각하면 Balance를 선택하세요 — 속도 제한 시 즉시 계정 전환합니다.

성능 우선 모드

요청이 무상태(예: 이미지 생성, 독립 쿼리)인 경우 PerformanceFirst를 시도해 보세요. 스티키 세션 및 60초 창 재사 건너뜀으로 연속 요청이 다른 계정으로 쉽게 떨어지게 합니다.

3단계: 계정 로테이션이 정상 작동하는지 확인

이유: 시스템이 자동으로 계정을 전환할 수 있는지 확인합니다.

방법 1: 응답 헤더 보기

curl 또는 자신의 클라이언트로 응답 헤더를 인쇄하고 X-Account-Email이 변경되는지 관찰합니다.

방법 2: 로그 보기

로그 파일(시스템 위치에 따라 다름)을 열고 🔄 [Token Rotation]을 검색합니다:

🔄 [Token Rotation] Accounts: [
  "[email protected](protected=[])",
  "[email protected](protected=[])",
  "[email protected](protected=[])"
]

방법 3: Proxy Monitor 사용

Monitor 페이지에서 요청 로그를 확인하고 다음을 중점적으로 봅니다:

  • Account 필드가 다른 계정 간에 전환되는지
  • Status가 429인 요청 후, 성공한 요청이 다른 계정을 사용했는지

예상 결과:

  • 특정 계정이 429를 반환한 후 후속 요청이 자동으로 다른 계정으로 전환됩니다.
  • 여러 요청이 동일한 계정을 사용하고 모두 실패하면 스케줄링 구성 문제일 수 있습니다.

4단계: 계정 우선순위 최적화

이유: 시스템이 높은 할당량/높은 등급 계정을 우선 사용하도록 하여 429 확률을 줄입니다.

TokenManager에서 시스템은 계정 선택 전 계정 풀에 대해 한 번 정렬을 수행합니다(🔄 [Token Rotation] Accounts: ...를 인쇄함):

  1. 구독 등급 우선: ULTRA > PRO > FREE
  2. 할당량 백분율 우선: 동일 등급 내에서 할당량이 높은 순
  3. 정렬 진입점: 이 정렬은 프록시 측에서 발생하며, 최종적으로 어떤 계정을 사용하는지는 프록시 측 정렬 + 가용성 판단을 기준으로 합니다.

스마트 정렬 원리(프록시 측)

우선순위는 ULTRA > PRO > FREE입니다. 동일 구독 등급 내에서 remaining_quota(계정 최대 남은 할당량 백분율) 기준 내림차순입니다.

작업:

  • 계정을 드래그하여 표시 순서 조정(선택 사항)
  • 할당량 새로고침(Accounts → 모든 할당량 새로고침)
  • 계정의 구독 등급과 할당량 확인

일반적인 문제

❌ 오류 1: 429를 "모델 용량 부족"으로 오해

현상: 429 오류를 보면 모델 용량이 부족하다고 생각합니다.

올바른 이해:

  • 429는 속도 제한이지 용량 문제가 아님
  • 계정을 추가하면 429 확률을 낮출 수 있음
  • 스케줄링 모드를 조정하면 전환 속도를 높일 수 있음

❌ 오류 2: 할당량 보호 임계값이 너무 높게 설정됨

현상: 할당량이 충분한데 시스템이 계속 계정을 건너뜁니다.

원인: Quota Protection은 임계값보다 낮은 모델을 계정의 protected_models에 추가하고, 프록시는 스케줄링 시 "보호된 모델"을 건너뜁니다. 임계값이 너무 높으면 사용 가능한 계정이 과도하게 제외될 수 있습니다.

수정:

  • Settings → Quota Protection로 돌아가서 모니터링 모델과 임계값 조정
  • 어떤 모델이 보호되었는지 이해하려면 계정 데이터에서 protected_models 확인

❌ 오류 3: 고정 계정 모드로 인해 로테이션 불가

현상: Preferred Account를 설정했지만 해당 계정이 속도 제한된 후 시스템이 "멈춥니다".

원인: 고정 계정 모드에서는 시스템이 지정된 계정을 우선 사용하고, 계정을 사용할 수 없을 때만 라운드 로빈으로 강등합니다.

수정:

  • 고정 계정이 필요하지 않으면 Preferred Account를 비우세요.
  • 또는 고정 계정의 할당량이 충분한지 확인하여 속도 제한을 방지하세요.

확인 체크리스트 ✅

  • [ ] 할당량 부족과 상류 속도 제한을 구별할 수 있음
  • [ ] Proxy Monitor에서 429 오류 세부 정보를 보는 방법을 알고 있음
  • [ ] 세 가지 스케줄링 모드의 차이와 사용 시나리오를 이해함
  • [ ] 계정 로테이션이 정상 작동하는지 확인하는 방법을 알고 있음
  • [ ] 계정 우선순위를 최적화하고 할당량 보호 정책을 확인할 수 있음

자주 묻는 질문

Q1: 여러 계정이 있는데 왜 여전히 429를 만나나요?

A: 가능한 원인:

  1. 모든 계정이 동시에 속도 제한 트리거(요청 빈도가 너무 높음)
  2. 연속 요청이 "60초 창 재사" 하에서 계속 동일 계정을 재사용하여 단일 계정을 속도 제한까지 쉽게 끌어올림
  3. 할당량 보호가 사용 가능한 계정을 잘못 제외함
  4. 계정 총수가 요청 빈도를 지원하기에 충분하지 않음

해결:

  • 더 많은 계정 추가
  • PerformanceFirst 모드 사용
  • Quota Protection이 사용하려는 모델을 protected_models에 추가했는지 확인(필요시 모니터링 모델과 임계값 조정)
  • 요청 빈도 낮추기

Q2: 429 오류가 자동으로 재시도되나요?

A: 단일 요청 내에서 자동으로 재시도합니다. 재시시 횟수 상한은 보통 3회이며, 구체적인 계산 방식은 min(3, 계정 풀 크기)이며 최소 1회 시도합니다.

재시시 횟수 예:

  • 계정 풀 1개 계정 → 1회 시도(재시도 안 함)
  • 계정 풀 2개 계정 → 2회 시도(1회 재시도)
  • 계정 풀 3개 이상 계정 → 3회 시도(2회 재시도)

대략적인 흐름:

  1. 속도 제한/과부하 정보 기록(RateLimitTracker에 진입)
  2. 대기 시간을 구문 분석할 수 있으면(예: RetryInfo.retryDelay / quotaResetDelay), 짧은 시간 동안 기다린 후 계속
  3. 재시시 시 계정 강제 로테이션(attempt > 0일 때 force_rotate=true), 다음 사용 가능한 계정으로 상류 요청 시도

모든 시도가 실패하면 프록시는 오류를 클라이언트에 반환합니다. 동시에 응답 헤더(예: X-Account-Email) 또는 Proxy Monitor에서 실제 사용한 계정을 볼 수 있습니다.

Q3: 특정 계정이 속도 제한된 기간을 어떻게 확인하나요?

A: 두 가지 방법이 있습니다:

방법 1: 로그 확인, rate-limited 검색

🔒 [FIX #820] Preferred account [email protected] is rate-limited, falling back to round-robin

방법 2: 로그에 남은 대기 시간 표시

All accounts are currently limited. Please wait 30s.

Q4: 할당량 보호와 속도 제한은 같은 것인가요?

A: 아닙니다.

특징할당량 보호속도 제한 추적
트리거 조건모델 할당량이 임계값보다 낮음429 오류 수신
작용 범위특정 모델전체 계정
지속 시간할당량이 회복될 때까지상류 결정(보통 몇 초에서 몇 분)
동작해당 모델 건너뜀해당 계정 건너뜀

Q5: 계정을 즉시 강제 전환하려면 어떻게 하나요?

A: "다음 요청이 더 쉽게 계정을 바꾸도록 만드는" 관점에서 접근할 수 있습니다:

  1. 스케줄링 측면: PerformanceFirst로 전환, 스티키 세션 및 60초 창 재사 건너뜀
  2. 고정 계정: Preferred Account가 활성화되어 있으면 먼저 비우세요. 그렇지 않으면 고정 계정을 우선 사용함(속도 제한/보호될 때까지)
  3. 계정 풀: 계정 수 증가, 단일 계정이 속도 제한될 때 대체 계정을 더 쉽게 찾기

단일 요청 내에서 프록시 자체도 재시시 시 계정을 강제 로테이션합니다(attempt > 0이면 force_rotate=true 트리거), 하지만 재시시 횟수는 상한 제한을 받습니다.

이 과정 요약

  • Antigravity Tools에서 429는 "상류가 일시적으로 사용할 수 없음"을 나타내는 신호이며, 속도 제한, 할당량 고갈, 모델 용량 부족 등 원인일 수 있음
  • 프록시는 냉각 시간을 기록하고 단일 요청의 재시시에서 계정 로테이션을 시도(하지만 재시시 횟수는 제한됨)
  • 스케줄링 모드, Quota Protection, 계정 수는 429 확률과 복구 속도에 영향을 미침
  • Proxy Monitor, 응답 헤더 X-Account-Email 및 로그로 빠르게 문제를 찾을 수 있음

다음 과정 예고

다음 과정에서는 **404/경로 호환성 문제: Base URL, /v1 접두사 및 "중첩 경로" 클라이언트**를 학습합니다.

배울 내용:

  • 가장 일반적인 연결 오류(404)가 어떻게 발생하는지
  • 다른 클라이언트의 base_url 연결 차이
  • 404 문제를 빠르게 수정하는 방법

부록: 소스 코드 참조

클릭하여 소스 코드 위치 펼치기

업데이트 시간: 2026-01-23

기능파일 경로행 번호
429 재시시 지연 구문 분석(RetryInfo / quotaResetDelay)src-tauri/src/proxy/upstream/retry.rs38-67
Duration 구문 분석 도구src-tauri/src/proxy/upstream/retry.rs11-35
스케줄링 모드 열거형(CacheFirst/Balance/PerformanceFirst)src-tauri/src/proxy/sticky_config.rs3-12
속도 제한 원인 구문 분석 및 기본 냉각 정책src-tauri/src/proxy/rate_limit.rs5-258
MAX_RETRY_ATTEMPTS 상수 정의(OpenAI handler)src-tauri/src/proxy/handlers/openai.rs14
재시시 횟수 계산(max_attempts = min(MAX_RETRY_ATTEMPTS, pool_size))src-tauri/src/proxy/handlers/openai.rs830
OpenAI handler: 429/5xx 시 속도 제한 표시 및 재시도/로테이션src-tauri/src/proxy/handlers/openai.rs349-389
계정 정렬 우선순위(ULTRA > PRO > FREE + remaining_quota)src-tauri/src/proxy/token_manager.rs504-538
60초 창 재사 + 속도 제한/할당량 보호 회피src-tauri/src/proxy/token_manager.rs624-739
속도 제한 기록 진입점(mark_rate_limited)src-tauri/src/proxy/token_manager.rs1089-1113
429 정확한 잠금/실시간 할당량 새로고침/강등 정책(mark_rate_limited_async)src-tauri/src/proxy/token_manager.rs1258-1417

핵심 상수:

  • MAX_RETRY_ATTEMPTS = 3: 단일 요청 내 최대 재시시 횟수(OpenAI/Gemini handler)
  • 60: 60초 창 재사(PerformanceFirst 외 모드에서만 활성화)
  • 5: 토큰 획득 시간 초과(초)
  • 300: 토큰 사전 새로고침 임계값(초, 5분)

핵심 함수:

  • parse_retry_delay(): 429 오류 응답에서 재시시 지연 추출
  • get_token_internal(): 계정 선택과 로테이션의 핵심 로직
  • mark_rate_limited(): 계정을 속도 제한 상태로 표시