Gemini API Flex 운영법: 429·503 재시도와 지연 시간을 제품 설계에 반영하는 방법
요약: Gemini API Flex는 비용을 낮추는 선택지이지만, 일반 API 호출처럼 동기 응답을 기대하면 운영 장애로 이어질 수 있습니다. Google 문서의 핵심은 명확합니다. Flex 용량이 부족해도 서버가 자동으로 Standard tier로 올려주지 않으며, 개발자가 직접 client-side retry와 exponential backoff를 구현해야 합니다. 따라서 Flex는 “싸게 호출하는 옵션”이 아니라 “지연과 실패를 제품 흐름에 포함하는 설계”입니다.
Flex를 쓰면 안 되는 작업부터 구분해야 한다
Flex 같은 저비용 추론 옵션은 매력적입니다. 배치 요약, 대량 문서 분류, 로그 분석, 백오피스 리포트처럼 즉시 응답이 필요 없는 작업에서는 비용을 줄일 수 있습니다. 하지만 사용자 앞에서 바로 답을 보여줘야 하는 기능에 무심코 붙이면 문제가 생깁니다.
예를 들어 결제 화면에서 “AI가 추천 쿠폰을 계산 중”인데 Flex 요청이 429나 503으로 돌아오거나 몇 분씩 늦어지면 사용자는 결제를 포기합니다. IDE 안에서 코드 자동완성에 Flex를 쓰면 개발자는 입력 흐름이 끊겨 바로 기능을 끕니다. 반대로 야간에 고객 문의 10만 건을 분류하거나, 하루치 리뷰를 요약하거나, 마케팅 문구 후보를 생성하는 작업은 몇 분 늦어져도 괜찮습니다.
따라서 첫 번째 기준은 단순합니다.
- 즉시 응답이 UX의 일부인 기능: Standard 또는 낮은 지연 모델.
- 지연을 화면에 설명할 수 있는 기능: Flex 후보.
- 백그라운드·배치·운영자용 기능: Flex 우선 검토.
Flex를 “실패해도 나중에 다시 하면 되는 작업”에 붙이면 강점이 살아납니다. “지금 이 순간 답이 없으면 사용자가 떠나는 작업”에 붙이면 비용 절감보다 이탈 비용이 커집니다.
429와 503은 예외가 아니라 정상 흐름으로 봐야 한다
Google의 Flex inference 설명에서 중요한 문장은 두 가지입니다. Flex capacity가 가득 찼을 때 시스템이 자동으로 Standard tier로 업그레이드하지 않는다는 점, 그리고 retry는 개발자가 직접 구현해야 한다는 점입니다. 이 말은 429와 503을 “장애 상황”이 아니라 “예상 가능한 상태”로 다뤄야 한다는 뜻입니다.
나쁜 구현은 이렇게 생겼습니다.
- 요청 실패 시 즉시 같은 요청을 반복한다.
- 모든 HTTP 에러를 재시도한다.
- 사용자 요청 스레드를 계속 붙잡고 기다린다.
- timeout을 길게만 잡고 상태 저장을 하지 않는다.
- 실패 로그에 prompt 일부를 그대로 남긴다.
좋은 구현은 반대입니다. 재시도 대상은 429와 503처럼 일시적 용량 문제에 한정합니다. Retry-After 헤더가 있으면 우선 따릅니다. 없으면 exponential backoff와 jitter를 씁니다. 같은 순간에 수천 개 작업이 동시에 재시도하지 않도록 full jitter를 넣습니다. 요청 상태는 DB나 큐에 저장하고, 사용자는 작업 ID로 진행 상태를 확인합니다.
기본값 예시는 다음 정도가 현실적입니다.
- 첫 재시도: 1~2초 사이 랜덤.
- 두 번째: 2~5초 사이 랜덤.
- 세 번째: 5~15초 사이 랜덤.
- 네 번째: 15~30초 사이 랜덤.
- 최대 시도: 4~5회.
- 최종 실패: Standard fallback 또는 “나중에 다시 처리” 큐로 이동.
중요한 건 “재시도 횟수”보다 “재시도 폭주를 막는 것”입니다. 용량이 부족한 상황에서 모든 워커가 같은 간격으로 재요청하면 장애를 키웁니다.
제품 화면에는 작업 상태가 필요하다
Flex를 백엔드에만 넣고 프론트엔드는 그대로 두면 사용자는 멈춘 화면을 보게 됩니다. 지연 가능성이 있는 추론은 UI 상태를 명확히 나눠야 합니다.
추천 상태는 다섯 가지입니다.
- queued: 요청을 받았고 아직 실행 전.
- running: 모델 호출 또는 후처리 중.
- retrying: 일시적 용량 문제로 재시도 대기 중.
- completed: 결과 생성 완료.
- failed: 재시도 한도 초과 또는 입력 오류.
여기서 retrying을 숨기지 않는 게 중요합니다. 내부적으로는 정상 흐름이지만, 사용자에게 아무 설명이 없으면 장애처럼 보입니다. 예를 들어 “AI 분석 대기열이 많아 1~3분 정도 걸릴 수 있습니다. 완료되면 알림으로 알려드릴게요.”처럼 말하면 이탈이 줄어듭니다.
제품에 따라 fallback도 다르게 설계해야 합니다. 운영자용 리포트는 다음 배치로 넘겨도 됩니다. 유료 사용자 대시보드는 Standard tier로 승격해도 됩니다. 무료 기능은 하루 처리량 제한을 두고 다음날 다시 시도하게 할 수 있습니다. 같은 Flex라도 가격 정책과 SLA에 따라 흐름이 달라집니다.
큐와 idempotency가 없으면 중복 과금이 생긴다
재시도를 구현할 때 가장 흔한 실수는 idempotency를 빼먹는 것입니다. 네트워크 timeout이 났다고 해서 모델이 실제로 실행되지 않았다는 뜻은 아닙니다. 클라이언트는 응답을 못 받았지만 서버 쪽에서는 처리가 끝났을 수 있습니다. 이때 같은 작업을 새 요청으로 계속 보내면 중복 결과와 중복 비용이 생깁니다.
작업 단위로 idempotency key를 만들어야 합니다. 예를 들어 userId + documentId + jobType + contentHash를 묶어 키로 씁니다. 같은 문서에 같은 분석 요청이 이미 queued 또는 running이면 새 작업을 만들지 않고 기존 작업 ID를 돌려줍니다. completed 상태라면 캐시된 결과를 반환합니다.
큐 구조도 단순하게 시작할 수 있습니다.
- jobs 테이블: id, user_id, job_type, status, input_hash, attempt_count, next_run_at, result_url, error_code.
- worker: next_run_at이 지난 queued/retrying 작업을 가져와 실행.
- lock: 같은 작업을 두 워커가 동시에 처리하지 않도록 lease_time 사용.
- dead letter: 최대 재시도 초과 작업 저장.
이 정도만 있어도 Flex 운영 품질이 크게 달라집니다. 처음부터 복잡한 워크플로우 엔진이 필요하진 않습니다. 중요한 건 요청과 결과를 HTTP 연결 수명에 묶지 않는 것입니다.
관측 지표는 latency 평균보다 p95와 실패 원인을 봐야 한다
Flex 운영에서 평균 응답 시간은 별로 쓸모가 없습니다. 대부분 빨리 끝나고 일부가 오래 걸리는 분포라면 평균은 문제를 숨깁니다. 제품 경험을 망치는 건 p95, p99, retry storm, 최종 실패율입니다.
대시보드에는 최소한 다음 지표가 있어야 합니다.
- flex_jobs_created: 생성된 작업 수.
- flex_jobs_completed: 완료된 작업 수.
- flex_final_failure_rate: 재시도 후 최종 실패율.
- flex_retry_count_by_status: 429, 503별 재시도 수.
- flex_queue_wait_p95: 큐에서 실행 전까지 기다린 시간.
- flex_end_to_end_p95: 요청부터 결과까지 전체 시간.
- fallback_to_standard_count: Standard로 승격한 횟수.
- duplicate_suppressed_count: idempotency로 막은 중복 수.
이 지표가 있어야 “Flex가 싸다”가 아니라 “어떤 기능에서 싸고, 어떤 기능에서 사용자 경험을 해치는지”를 판단할 수 있습니다.
오늘 적용할 체크리스트
- Flex 적용 후보를 즉시 응답, 지연 허용, 배치 작업으로 분류합니다.
- 429와 503에만 제한적으로 재시도하고 Retry-After를 우선합니다.
- exponential backoff에 full jitter를 넣어 재시도 폭주를 막습니다.
- 작업 상태를 queued, running, retrying, completed, failed로 분리합니다.
- HTTP 요청 안에서 끝내려 하지 말고 큐와 워커로 처리합니다.
- idempotency key로 중복 실행과 중복 과금을 막습니다.
- p95 지연, 최종 실패율, fallback 횟수를 대시보드에 올립니다.
- 유료 기능과 무료 기능의 fallback 정책을 다르게 둡니다.
Flex는 비용 절감 기능이 맞습니다. 하지만 제대로 쓰려면 API 옵션이 아니라 제품 운영 설계로 접근해야 합니다. 지연, 재시도, 중복 방지, 상태 표시를 함께 넣은 팀만 실제 비용 절감과 안정성을 동시에 얻습니다.