Gemini API Flex 운영법: 503·429 재시도와 10분 타임아웃 설계
Gemini API Flex inference를 실제 서비스에 붙일 때 가장 먼저 바꿔야 할 것은 프롬프트가 아니라 운영 코드입니다. Flex는 standard tier보다 저렴하지만, 요청이 queue에 머무를 수 있고 capacity가 부족하면 503 또는 429가 발생할 수 있습니다. 따라서 “한 번 호출하고 실패하면 에러”라는 기본 HTTP 사고방식으로는 안정적으로 운영하기 어렵습니다.
이 글은 Flex를 백그라운드 agent, 평가 자동화, 데이터 보강 작업에 붙일 때 필요한 retry, timeout, fallback 기준을 정리합니다. 핵심은 비용 절감보다 예측 가능한 실패 처리입니다.
기본 호출 패턴
Flex 사용 방식은 간단합니다. Gemini Interactions API 호출에 service_tier: flex를 추가하면 됩니다. REST 기준으로는 다음 구조입니다.
{
"model": "gemini-3.5-flash",
"input": "Analyze this dataset for trends...",
"service_tier": "flex"
}
문제는 이 한 줄 뒤에 숨어 있습니다. Flex는 synchronous interface를 유지하지만, latency target이 seconds가 아니라 minutes 범위입니다. 문서상 1~15분 target으로 설명됩니다. 대부분의 서버, worker, HTTP client 기본 timeout은 이보다 짧습니다. Node.js, Python requests, serverless function, queue worker가 각각 다른 timeout을 갖고 있으면 중간에서 끊깁니다.
timeout은 호출 지점별로 맞춰야 한다
첫 번째 원칙은 end-to-end timeout을 맞추는 것입니다. API client만 600초로 늘려도, 앞단 job runner가 120초에 종료되면 의미가 없습니다. 최소한 다음 지점을 확인해야 합니다.
- HTTP client timeout
- queue worker job timeout
- serverless function timeout
- reverse proxy idle timeout
- observability agent timeout
- 전체 workflow deadline
Flex 작업은 가능하면 사용자 요청 thread에서 떼어내야 합니다. 사용자가 버튼을 누른 뒤 결과를 기다리는 구조라면 Standard tier가 맞습니다. Flex는 job id를 반환하고, 완료 후 알림이나 상태 갱신으로 보여주는 구조가 더 안전합니다.
503과 429를 다르게 다루기
503 Service Unavailable은 capacity 부족 또는 system congestion으로 볼 수 있습니다. 이 경우 즉시 같은 요청을 반복하는 것은 좋지 않습니다. exponential backoff와 jitter를 넣어야 합니다. 예를 들어 30초, 90초, 3분으로 늘리되, 약간의 랜덤 값을 섞어 여러 worker가 동시에 재시도하지 않게 합니다.
429 Too Many Requests는 rate limit 또는 resource exhaustion입니다. 이 경우에는 조직 전체 요청량과 연결됩니다. 단일 job만 재시도해서 해결되지 않을 수 있습니다. 429가 반복되면 worker concurrency를 낮추거나, 다음 배치로 넘기는 편이 낫습니다.
중요한 것은 두 에러 모두 “버그”가 아니라 운영 조건이라는 점입니다. 알림을 error channel에만 쏟아내면 금방 무시됩니다. 실패율, 재시도 후 성공률, 최종 포기율을 지표로 봐야 합니다.
fallback은 자동이 아니라 정책이다
Google 문서는 Flex capacity가 부족할 때 서버가 자동으로 Standard tier로 올리지 않는다고 설명합니다. 예상치 못한 비용 증가를 막기 위해서입니다. 따라서 fallback은 애플리케이션이 직접 결정해야 합니다.
추천 기준은 세 단계입니다.
- 낮은 우선순위: Flex 실패 시 다음 주기로 연기
- 중간 우선순위: 2~3회 재시도 후 실패 큐로 이동
- 높은 우선순위: 정해진 예산 내에서 Standard tier로 전환
예를 들어 nightly eval은 낮은 우선순위입니다. 오늘 실패해도 내일 다시 돌리면 됩니다. 반면 고객에게 오늘 중 전달해야 하는 리포트 생성은 중간 또는 높은 우선순위가 될 수 있습니다.
idempotency 없이 재시도하지 말 것
Flex를 데이터 변경 작업에 붙일 때는 idempotency key가 필요합니다. 같은 고객 프로필 보강 요청이 재시도로 두 번 성공하면, 태그가 중복되거나 마지막 결과가 이전 결과를 덮을 수 있습니다.
작업 테이블에는 최소한 다음 필드를 두는 것이 좋습니다.
- job_id
- input_hash
- service_tier
- attempt_count
- status
- last_error_code
- started_at, completed_at
- output_version
이 구조가 있어야 실패한 작업만 다시 돌리고, 이미 성공한 작업은 건너뛸 수 있습니다.
관측 지표
Flex 도입 후에는 평균 latency보다 p95, p99가 더 중요합니다. 사용자가 기다리지 않는 작업이라도 workflow deadline을 넘기면 다음 단계가 밀립니다. 또한 비용 절감률만 보지 말고 재시도 비용을 포함해야 합니다. 50% 할인이라도 실패와 재시도가 많으면 실제 절감률은 줄어듭니다.
추천 지표는 다음과 같습니다.
- Flex 요청 수와 Standard 요청 수
- 503, 429 비율
- retry 후 성공률
- 최종 실패율
- p50, p95, p99 latency
- 작업당 평균 토큰 비용
- fallback으로 Standard 전환된 비율
실행 체크리스트
- Flex 작업을 사용자 요청 thread에서 분리했는가?
- timeout을 600초 이상으로 맞췄는가?
- 503과 429에 서로 다른 backoff 정책을 적용했는가?
- fallback 기준을 우선순위와 예산으로 정했는가?
- job id와 input hash로 idempotency를 보장하는가?
- retry 비용을 포함한 실제 절감률을 계산하는가?
- Flex worker concurrency를 별도로 제한하는가?
Flex는 잘 쓰면 비용을 크게 줄이지만, 대충 붙이면 “느리고 가끔 실패하는 API”가 됩니다. 운영 코드를 먼저 설계하고, 그다음에 할인율을 기대하는 순서가 맞습니다.