Skip to content

Feature: surface ChatGPT public-endpoint queue latency and granted service tier (proxy waits ~11s on gpt models vs 0.2-2s on DeepSeek/Kimi) #2455

Closed

Description

@nowhere1975

Area

Proxy and routing

What are you trying to accomplish?

Users who route ChatGPT-family models (gpt-5.x) through the opencodex proxy experience a ~11 s first-response wait before any model work starts, while DeepSeek and Kimi through the same proxy answer in 0.2-2 s. I want to understand why this is expected (or fix it), and be able to see whether the requested priority service tier was actually granted - so I can choose the right provider/model for latency-sensitive work instead of guessing.

Measured on opencodex 2.28.0 (macOS, same machine, same Clash proxy, same prompt, /v1/responses streaming):

model response.created first output total
deepseek/deepseek-v4-flash 0.2 s 0.7 s 1.0 s
deepseek/deepseek-reasoner 0.2 s 1.0 s 1.2 s
kimi/kimi-for-coding 0.9 s 1.4 s 1.8 s
kimi/k3-256k 1.9 s 2.2 s 2.7 s
gpt-5.6-luna ~11 s 13-20 s 13-25 s
gpt-5.6-terra ~11 s 21-31 s 23-98 s

Network segments are healthy (loopback ~0.1 s; proxy to chatgpt.com TTFB ~0.8 s). response.created stays ~10.7-11.5 s across two pool accounts and three reasoning efforts.

What prevents this today?

  • ChatGPT-family requests through the proxy always use the public API endpoint (chatgpt.com/backend-api/codex), which queues ~10 s; the native Codex app channel is not reachable through a proxy by design of the pool architecture.
  • service_tier: priority is forwarded (fastwire) but the backend echoes auto; request logs only show tierOutcome.confirmation: assumed, so users cannot tell whether priority was granted.
  • No documentation explains this channel/queue difference, so the proxy looks slow/broken when it is behaving as designed.

What should OpenCodex do?

  1. Document the latency/channel behavior for ChatGPT-family models (expected queue latency through the public endpoint, and why the native app channel is not available via the proxy) - ideally in the docs and in ocx doctor output.
  2. Echo the backend-granted service tier (observed in response.created) into the request log / dashboard instead of confirmation: assumed.
  3. Consider a native-channel bypass or explicit single-account direct mode for gpt models as a latency escape hatch for pool users.

Example usage or interface

$ ocx logs --json
... "tierOutcome": { "wireKind": "service-tier", "wireValue": "priority", "confirmation": "confirmed" } ...

$ ocx doctor
[WARN] ChatGPT public endpoint queue latency observed (~10s before first response); expected through the proxy. Use DeepSeek/Kimi providers for latency-sensitive work, or run the Codex app natively for the app channel.

Alternatives or workarounds

  • Use DeepSeek/Kimi providers for latency-sensitive work (works today, 1-3 s).
  • Run the Codex desktop app natively (ocx restore) to get the app channel, at the cost of losing the account pool.

Additional context

Related discussion: #2300 (proxy latency vs native subscription). Original freeform report was auto-closed by the issue-quality bot for not using a template; this report follows the Feature proposal template.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. added
    enhancementNew feature or request
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Aug 23, 2026
  2. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 42 / 80

    설명: 이 이슈는 프록시로 지피티 계열을 보내면 첫 응답이 약 11초이고, 딥시크와 키미는 0.2에서 2초라고 한다. 작성자는 공개 엔드포인트 대기와, 우선 등급이 진짜로 주어졌는지 로그에 안 보인다고 적었다. 버전은 2.28.0 이다. 같은 자리, 같은 프롬프트, 스트림 응답 길이다. 관련 토론은 2300 이다. 품질 봇이 서식 없는 글을 닫아서 이번 글은 기능 서식이다. 지금 CURRENT dev HEAD 는 35a89903c 이다. 이번 시간에 origin/dev 는 6b0f61f64 에서 여기로 왔다. 새 머지는 2454 와 2456 이다. package.json 은 2.27.0 이다. src/config.ts 는 3238줄이다. src/runtime 폴더는 지금 HEAD 에 없다.

    표는 이렇다. 딥시크 플래시 생성 0.2초, 키미 코딩 0.9초, 루나와 테라는 생성 약 11초. 고리 백은 0.1초, 프록시에서 챗지피티 첫 바이트는 0.8초다. 생성 시각이 계정 둘과 추론 강도 셋에서 10.7에서 11.5초로 같다. 작성자는 프록시가 공개 에이피아이 챗지피티 백엔드 코덱스 길을 쓰고, 그 길이 약 10초 줄을 선다고 본다. 네이티브 앱 길은 풀 구조상 프록시로 안 열린다고 적었다. 우선 등급은 패스트와이어로 나가지만 백엔드는 오토를 메아리친다. 로그의 등급 결과는 가정이다.

    지금 HEAD 의 src/providers/fastwire.ts 339줄은 와이어가 우선이면 적용으로 두고 확인은 가정으로 시작한다. 350줄 관찰자가 응답 등급을 보면, 우선이면 확인, 아니면 내려감이다. src/server/request-log.ts 619줄은 응답 페이로드의 service_tier 칸을 그 관찰자에 넘긴다. 채팅 어댑터도 청크 등급을 넘긴다. 작성자가 가정만 본다면, 공개 응답 길의 생성 사건이 그 관찰자에 안 들어왔거나, 백엔드 오토가 확인으로 안 바뀐 것이다. 오토면 내려감이 맞다. 가정이 남으면 관찰이 빠진 것이다. 닥터 출력에 이 대기 경고는 지금 HEAD 에 없다.

    부탁은 세 갈래다. 문서와 닥터에 공개 길 대기를 적는다. 로그에 백엔드가 준 등급을 확인으로 남긴다. 네이티브 길 우회나 단계정 직접 모드를 본다. 앞의 둘은 이 이슈 범위다. 세 번째는 풀 구조를 바꾸는 큰일이다. 이 이슈로 열지 말 것. 2300 은 프록시가 네이티브 구독보다 느리다는 다른 글이다. 이번 글이 그 글을 닫지 않는다. 2454 할당량 화면과 2451 wait 밑줄과 2458 동영상 가드는 다른 길이다.

    사용자 길이로는 지피티가 11초 걸려 느려 보이지만 공개 길의 줄일 수 있어서 42. 제품 구멍이라기보다 설명과 로그 칸이다. 카탈로그 팁은 Ox Alpha x-preview-f-free + deepseek-v4-flash-vision-exp. Cursor 정적 카탈로그는 opus-4-8-fast / opus-5-fast. 2334 CursorCredentialRouter 는 여전히 src/providers/cursor-pool.ts 모듈+테스트만 있고 어댑터에 연결되지 않았다. 2332 H2 는 discovery 전용. 2320 overflow + 2342 는 이미 dev. 2188 사이드카는 이미 dev. 2361 __omit__ 는 이미 HEAD 다. 이번 시간 2454 콤보 할당량 화면이 착지했다. combo-stream-preflight.ts 는 지금 HEAD 에 있다. src/lib/bounded-body.ts 128줄 취소 없는 던짐과 2426 나가는 크기 가드는 그대로다. 2451 wait 허용 목록은 아직 하이픈이다.

    src/providers/fastwire.ts 라인 342 - 와이어가 우선이면 확인은 가정으로 시작한다
    src/providers/fastwire.ts 라인 367 - 응답 등급이 우선이면 확인으로 바뀐다. 오토면 내려감이다
    src/server/request-log.ts 라인 619 - 응답 페이로드의 service_tier 를 관찰자에 넘긴다
    이슈 2300 - 프록시 지연 토론이다. 이번 글이 그 글을 닫지 않는다
    닥터 출력 - 지금 HEAD 에 공개 길 대기 경고가 없다

    메인테이너의 판단이 필요한 지점

    • 문서와 닥터 경고만 넣을지, 생성 사건의 등급을 관찰자에 꼭 넣을지. 둘 다 이 이슈 범위다. 가정이 남으면 관찰이 빠진 것이다
    • 네이티브 길 우회를 이 이슈에 넣을지. 풀 구조라서 넣지 말 것
    • 2300 을 닫을지. 닫지 말 것. 이번은 공개 길 설명과 등급 확인이다
    • 우선을 강제로 다시 보낼지. 백엔드가 오토를 주면 내려감으로 남기는 편이 맞다

    너의 추천
    이슈는 열어 둔다. 문서와 닥터에 공개 길 약 10초 대기를 적는다. 생성 사건의 등급을 관찰자에 넣어 확인 또는 내려감이 로그에 남게 한다. 네이티브 우회는 이 이슈로 하지 말 것. 2300 과 2451 과 2458 은 닫지 않는다. 호출 길을 넓히지 말 것. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.

    이 댓글은 grok-bot이 작성했습니다

  3. abhisheksharma2411 commented on Sep 2, 2026

    @abhisheksharma2411
    Contributor

    I went to implement item 2 and found it already ships. Writing up what I traced so nobody builds it twice, on dev at 7d25f996.

    The granted tier is captured on the /v1/responses path. Every SSE payload goes through inspectResponseLogSsePayloadParsed → applyResponseLogMetadata, and that function unwraps the envelope before reading the field:

    // src/server/request-log.ts:634
    const source = "response" in payload && typeof payload.response === "object"
      ? payload.response
      : payload;
    ...
    const serviceTier = source.service_tier;              // :643
    if (typeof serviceTier === "string" && serviceTier.trim()) {
      if (sanitized) logCtx.responseServiceTier = sanitized;
      logCtx.activeTierMetadata?.observeResponseServiceTier(serviceTier);
    }

    Because it unwraps .response, the tier on a response.created event — which is where you observed it — is exactly what it reads.

    It reaches the dashboard too, in the logs model tooltip:

    // gui/src/pages/logs-model-title.ts:18
    log.responseServiceTier ? `responseTier=${log.responseServiceTier}` : undefined

    So responseServiceTier should already show the backend's answer alongside requestedTier and configuredTier. If it is blank for you on a gpt-5.x turn, that is a different and more interesting bug than the one filed, and worth saying so here.

    confirmation: assumed is deliberate for this route, not a missing feature. It is the one thing I would not change:

    // src/types/provider.ts:152
    // The ChatGPT-internal Codex backend returns `service_tier: "default"` on turns that were in
    // fact scheduled as priority, so treating its echo as a downgrade produced a false
    // `response-declined` on every Fast request (#2558).

    responseTierAuthoritative: false gates responseCanConfirmFast in fastwire.ts, so the echo is recorded but not allowed to promote to confirmed or demote to downgraded. Making assumed into confirmed here would reintroduce #2558. The honest state really is "we asked, and this backend cannot tell us" — and responseServiceTier is the raw evidence sitting next to it.

    What I think is genuinely left:

    1. Item 1, the documentation — nothing explains the ~11 s public-endpoint queue or why the native app channel is unavailable through the proxy, so the proxy reads as broken when it is behaving as designed. That looks like the highest value-per-line here.
    2. A note in ocx doctor, as you suggest, along the same lines.
    3. Item 3, the native-channel bypass — a real architectural question, well outside what I would fold into this.

    Happy to take item 1 as a docs PR if that is wanted, but I did not want to open a code PR against a premise that turned out not to hold. Thanks for the measurements table — the segment timings are what made it quick to rule the logging path in or out.

  4. added a commit that references this issue on Sep 9, 2026
    166309c
  5. lidge-jun commented on Sep 9, 2026

    @lidge-jun
    Owner

    Landed via #4091 at bb61007

    Closing as completed on current dev.

  6. added a commit that references this issue on Sep 17, 2026
    c5449e6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions