GPT Image 2 API가 느리거나 시간 초과될 때 바로 모델이 느리다고 결론 내리면 안 됩니다. 복잡한 프롬프트, 많은 참조 이미지, 높은 quality, 큰 size는 실제로 긴 생성 시간을 만들 수 있습니다. 그러나 운영 환경에서 보이는 “느림”은 브라우저 fetch, CDN, Worker, 리버스 프록시, gateway, SDK timeout, 또는 재시도 설계가 먼저 실패해서 생기는 경우가 많습니다. 첫 단계는 최적화가 아니라 시간 분해입니다.
| 보이는 증상 | 첫 분류 | 첫 안전 조치 |
|---|---|---|
| 첫 바이트가 늦지만 최종 이미지는 온다 | 긴 생성 또는 큐 대기 | 진행 상태를 보여주고 streaming 또는 비동기 job을 검토 |
| backend는 끝났는데 browser가 실패 | 가짜 시간 초과 | 실제 실패한 계층만 넓히고 전체 timeout은 그대로 둔다 |
| 재시도가 쌓이거나 429가 보인다 | retry 및 rate limit 압력 | 짧은 반복 재시도를 멈추고 reset header와 backoff를 쓴다 |
| gateway 경로에서만 느리다 | 경로 소유자 지연 | 같은 요청으로 더 직접적인 경로와 비교하고 익명화한 증거로 확인 |
key 교체, provider 변경, quality 하향, 무한 재시도는 첫 조치가 아닙니다. 먼저 어떤 시계가 실패했고, 어떤 시스템이 로그를 갖는지 확인해야 합니다.
긴 생성과 가짜 시간 초과를 먼저 나누기
duration_ms=90000 같은 단일 숫자는 충분하지 않습니다. 연결이 늦었는지, 첫 바이트가 늦었는지, 부분 이미지가 왔는지, 최종 이미지가 완성됐는지, 다운로드나 렌더링이 느렸는지, retry가 작업을 늘렸는지, 어느 계층이 timeout을 냈는지 분리해야 합니다.

한 image job에는 request_started_at, connect_ms, first_byte_ms, first_partial_image_ms, final_image_ms, download_ms, render_ms, retry_count, retry_reason, http_status, error_type, request_id, model, quality, size, format, route_owner를 함께 기록합니다. 그래야 network, model, file, browser, retry를 같은 사건 안에서 비교할 수 있습니다.
gpt-image-2라는 모델 이름은 충분한 소유자 정보가 아닙니다. OpenAI direct, Azure deployment, compatible gateway, reverse route는 같은 모델 라벨을 써도 timeout, headers, retries, log owner가 다릅니다. 경로가 다르면 같은 latency로 섞지 마세요.
이미지 생성에 맞는 timeout budget 만들기
모든 계층을 길게 바꾸는 것은 좋은 budget이 아닙니다. 브라우저는 사용자 상태를 보여주고, backend는 job을 관리하고, proxy는 upstream을 기다리고, queue는 작업 완료를 추적해야 합니다. frontend가 최종 이미지까지 동기 요청을 붙잡을수록 “backend는 아직 실행 중인데 browser는 실패”하는 가짜 장애가 늘어납니다.

| 계층 | 흔한 실패 | 더 나은 규칙 |
|---|---|---|
| 브라우저/모바일 | fetch가 backend보다 먼저 abort | job ID, progress stream, polling을 반환 |
| CDN/edge | platform limit이 긴 요청을 자름 | 이미지 생성을 짧은 edge path 밖으로 이동 |
| Worker | function timeout 먼저 도달 | long-running worker, queue, background job 사용 |
| 리버스 프록시 | idle/upstream timeout | 이미지 route만 조정 |
| gateway/provider | 내부 대기와 retry가 보이지 않음 | provider logs와 upstream status를 따로 확인 |
| SDK/HTTP client | local timeout 먼저 발생 | 제품 경로와 retry policy에 맞춘 명시 timeout 사용 |
사용자에게 빈 loading만 보여주면 중복 클릭이 늘어납니다. queued, generating, partial preview, finalizing, saved, failed at local timeout 같은 상태 언어를 쓰면 중복 생성과 support 혼선을 줄일 수 있습니다.
기준선을 잰 뒤 파라미터를 바꾸기
공식 이미지 생성 옵션은 실제로 지연에 영향을 줍니다. draft에서는 low quality가 빠르고, square output은 더 단순하며, latency가 중요한 preview에서는 JPEG가 PNG보다 유리할 수 있고, 복잡한 prompt는 오래 걸릴 수 있습니다. 하지만 이 사실은 모든 값을 동시에 바꾸라는 뜻이 아닙니다.
| 변경 | 좋아질 수 있는 점 | 잃을 수 있는 점 | 시도할 때 |
|---|---|---|---|
| quality low | draft 피드백 | 디테일, 텍스트, 완성도 | 아이디어, 썸네일, 내부 미리보기 |
| square output | 생성과 레이아웃 단순화 | 필요한 비율 | 후처리 crop 가능할 때 |
| JPEG | 전송과 decode | 투명도와 후작업 | preview 또는 사진형 출력 |
| PNG/WebP | 품질과 압축 제어 | 전송량과 처리 | production asset |
| 참조 이미지 축소 | upload/input 처리 | 스타일과 정체성 제어 | 참조가 과도할 때 |
| prompt 단순화 | 모델 작업량 | 지시 정밀도 | 느린 시계가 생성 단계일 때 |
품질이 제품 가치라면 지표만 보고 낮추지 마세요. 품질 분기는 /ko/blog/gpt-image-2-low-quality/, 큰 이미지 분기는 /ko/blog/gpt-image-2-4k-image-generation/로 보내고, 여기서는 clock과 owner를 유지합니다.
Streaming과 비동기로 체감 지연 줄이기
Streaming partial images는 최종 이미지 전에 진행 상태를 보여줍니다. 그러나 최종 계산이 반드시 빨라지는 것은 아닙니다. 로그에서는 first byte, first partial image, final image를 따로 기록해야 합니다.
Streaming이 제품 구조와 맞지 않으면 비동기 job이 더 안정적입니다. backend는 image job을 만들고 job id를 반환합니다. frontend는 polling하거나 상태를 구독합니다. 이렇게 하면 browser 요청이 전체 생성 시간을 들고 있지 않아도 되고, 실패 시에도 “아직 실행 중”과 “새 job이 필요”를 구분할 수 있습니다.
느린 요청을 rate limit 사고로 키우지 않기
local timeout 후 즉시 retry하면 upstream에서 아직 실행 중인 job과 새 job이 동시에 생길 수 있습니다. 여러 사용자가 같은 동작을 하면 RPM, TPM, IPM, daily limit, 429에 가까워집니다. retry가 나쁜 것이 아니라, 원래 job 상태를 모르는 retry가 위험합니다.
| 조건 | retry 규칙 |
|---|---|
| local timeout | 기존 job이 아직 실행 중인지 먼저 확인 |
| 429 또는 limit headers | reset header와 jitter backoff 사용 |
| 5xx | 최대 횟수를 둔 제한 retry |
| 사용자의 재클릭 | pending job 반환 또는 새 생성 확인 |
| gateway 내부 retry | 자체 retry와 별도 집계 |
429나 quota가 중심이 되면 /ko/blog/openai-api-rate-limit/와 /ko/blog/gpt-image-2-usage-limits/로 이동합니다. latency 복구가 숨은 limit 우회가 되면 안 됩니다.
OpenAI direct, Azure, gateway, reverse route 분리하기
OpenAI direct에서는 model id, endpoint, request id, status, headers를 봅니다. Azure는 deployment, region, quota, APIM, regional status를 봅니다. compatible gateway는 base URL owner, upstream mapping, provider timeout, retry policy, log visibility를 확인해야 합니다. reverse route는 account/session owner, hidden retries, policy boundary, support risk를 별도 분리합니다.
같은 prompt가 direct에서는 빠르고 gateway에서는 느리다면 모델만 원인이 아닙니다. gateway가 투명한 로그를 제공하지 못하고 local timeout과 upstream wait를 분리하지 못한다면 production latency diagnosis에는 약합니다. 비용이나 접속 경로 선택은 /ko/blog/gpt-image-2-api-cheap/로 넘기고, 지연 대응은 clock과 ownership에 집중합니다.
에스컬레이션에는 익명화한 증거 보내기

보낼 정보는 timestamp, timezone, 반복 여부, route owner, model, endpoint, streaming 여부, quality, size, format, reference images, first byte, partial image, final image, download, render, timeout layer, retry count, returned status, request id, worker/runtime, proxy, CDN, browser timeout, 최소 재현 조건입니다.
보내면 안 되는 것은 API key, token, private prompt, private image, customer identifier, IP, channel ID, account-pool details, raw logs입니다. 마지막 결정은 구체적이어야 합니다. 하나의 timeout만 넓히기, async job으로 이동, draft quality 낮추기, output format 변경, high-resolution 작업 분리, backoff 수정, 또는 로그를 가진 route owner에게 넘기기입니다.
최소 재현 테스트 만들기
주요 시계를 기록했다면 다음은 최소 재현 테스트입니다. 한 번의 테스트에서 route, quality, size, format, retry, timeout을 동시에 바꾸지 마세요. 여러 값을 동시에 바꾸면 빨라진 이유도, 여전히 느린 이유도 설명할 수 없습니다.
순서는 단순하게 둡니다. 먼저 같은 prompt, quality, size, format, route owner로 세 번 실행해 지연이 안정적인지 일시적인 변동인지 확인합니다. 다음에는 대기 방식만 바꿉니다. browser가 동기 요청으로 기다리는 방식과 backend가 job id를 반환하고 polling하는 방식을 비교해 browser timeout이 사라지는지 봅니다. 그다음 output format만 JPEG, PNG, WebP로 바꾸고 download_ms와 render_ms를 비교합니다. quality는 그 뒤에 low, medium, high로 나누어 봅니다. 마지막에만 OpenAI direct, Azure, gateway 같은 route owner를 비교합니다.
| 테스트 | 고정할 것 | 하나만 바꿀 것 | 판단할 것 |
|---|---|---|---|
| 기준선 | prompt, quality, size, format, route | 같은 조건 세 번 | 지연이 안정적인가 |
| 동기와 비동기 | prompt, 파라미터, route | 대기 방식 | browser timeout이 사라지는가 |
| 출력 형식 | prompt, quality, size, route | JPEG / PNG / WebP | download와 render 영향 |
| quality | prompt, size, format, route | low / medium / high | final_image_ms 변화 |
| route owner | prompt, 파라미터, retry policy | direct / Azure / gateway | 지연이 경로에 속하는가 |
high quality에서만 느리면 GPT Image 2 API 전체가 느리다고 쓰지 않습니다. browser 동기 path에서만 실패하면 upstream 문제라고 말하지 않습니다. gateway에서만 느리면 OpenAI direct 동작과 섞지 않습니다. 최소 재현의 목적은 책임을 넓히는 것이 아니라 고칠 수 있는 계층까지 좁히는 것입니다.
팀에서는 결과를 하나의 표에 남기는 것이 좋습니다. 시간, timezone, route owner, base URL 소유자, streaming 여부, async 여부, 파라미터, first byte, final image, 실패 계층, retry count, 비고가 있으면 support나 provider에게 넘길 때도 추측이 줄어듭니다.
운영 전 가드레일
느린 path를 고친 뒤에도 운영에는 guardrail이 필요합니다. Generate 버튼은 pending 상태를 가져야 하며 같은 job이 끝나기 전 두 번째 생성을 만들지 않아야 합니다. backend는 같은 user, 같은 prompt, 같은 파라미터, 같은 route owner의 pending job을 새로 만들지 말고 기존 상태를 반환해야 합니다. 오류 메시지는 local timeout, gateway timeout, upstream error, returned API error를 분리해야 합니다. 대시보드는 route owner별로 latency를 나누고 OpenAI direct, Azure, gateway, 자체 proxy 평균을 하나로 섞지 않아야 합니다.
성공한 job도 모니터링해야 합니다. 최종 이미지는 왔지만 first_byte_ms가 계속 길면 UX 문제입니다. final_image_ms는 짧지만 download_ms와 render_ms가 모바일에서 높다면 파일 전송이나 렌더링 문제입니다. retry_count는 낮은데 duplicate clicks가 많다면 인터페이스 상태 표현이 약한 것입니다. 성숙한 이미지 생성 운영은 성공률만 보지 않고 clock, user state, duplicate clicks, support packet readiness를 함께 봅니다.
경로를 넘나드는 비교에는 반드시 설명을 붙입니다. direct는 공식 모델과 파라미터 문제를 답하고, Azure는 deployment와 region 문제를 답하며, gateway는 중계 설정과 upstream mapping을 답하고, frontend는 browser timeout과 render 문제를 답합니다. 이 경계를 지키면 독자가 잘못된 계층을 고치지 않고, 팀도 private logs, account details, channel data를 공개 설명에 섞지 않게 됩니다.
자주 묻는 질문
GPT Image 2 API가 원래 느릴 수 있나요?
복잡한 이미지 생성은 오래 걸릴 수 있습니다. 하지만 browser나 proxy가 먼저 실패하면 정상 대기가 아니라 가짜 시간 초과입니다. first_byte_ms와 final_image_ms를 분리해 보세요.
60초 timeout은 짧나요?
복잡한 image job에서는 짧을 수 있습니다. 그래도 모든 timeout을 늘리지 말고, 실제 실패 계층만 이미지 route나 background job에 맞추세요.
Streaming이 최종 이미지를 빠르게 하나요?
보장하지 않습니다. 진행 상태를 보여주고 중복 클릭을 줄이는 데 의미가 있습니다. final image time은 따로 기록해야 합니다.
먼저 quality를 낮춰야 하나요?
draft나 preview라면 좋습니다. production asset은 먼저 slow clock을 측정하고, quality 변경은 controlled test로 하세요.
gateway가 느린지는 어떻게 보나요?
같은 prompt, quality, size, format을 더 직접적인 경로와 비교하세요. base URL owner, upstream status, retry count, first byte, final image time, status code를 기록합니다.



