Startup latency regressed in 0.117.0: codex blocks on app-server bootstrap before the TUI is interactive

Resolved 💬 1 comment Opened Apr 3, 2026 by aofei Closed Apr 3, 2026

What version of Codex CLI is running?

0.118.0

What subscription do you have?

ChatGPT Pro

Which model were you using?

gpt-5.4

What platform is your computer?

Darwin 25.4.0 arm64 arm

What terminal emulator and version are you using (if applicable)?

Ghostty

What issue are you seeing?

On 0.117.0 and 0.118.0, startup blocks for about 2-3s even on a warm start. On a cold start it is slower.

The delay happens before the TUI becomes interactive.

What steps can reproduce the bug?

  1. Sign in with ChatGPT auth.
  2. Launch codex in a normal terminal with no prompt.
  3. Measure the time from pressing Enter to the first interactive TUI frame.
  4. Repeat once with a warm cache and once with a cold or stale model cache.

What is the expected behavior?

Startup should reach an interactive TUI quickly.

In particular, login status detection should not require a full app-server bootstrap or block on network requests before the first interactive frame is shown.

Additional information

The regression was first noticeable in 0.117.0. 0.116.0 appeared almost instantly, essentially in the blink of an eye, on the same machine.

  • This looks like a regression introduced when the app-server TUI became the default and then the legacy TUI split was removed:
  • #15661 enable tui_app_server feature by default
  • #15922 remove the legacy TUI split
  • #16104 rename tui_app_server to tui
  • From source review, the blocking startup path appears to be:
  • run_ratatui_app() starts an onboarding app server
  • get_login_status() calls the full app_server.bootstrap() just to determine auth state
  • bootstrap() performs GetAccount, ModelList, and GetAccountRateLimits
  • Then the main app starts another app server, calls bootstrap() again, and synchronously calls start_thread()
  • Relevant code paths:
  • tui/src/lib.rs: run_ratatui_app(), get_login_status()
  • tui/src/app_server_session.rs: bootstrap(), start_thread()
  • app-server/src/codex_message_processor.rs: get_account(), get_account_rate_limits()
  • backend-client/src/client.rs: get_rate_limits_many()
  • Why this looks expensive even on a warm start:
  • GetAccount is sent with refresh_token: false, so it appears to use cached auth state
  • In my logs, ModelList was a cache hit on warm start
  • That leaves GetAccountRateLimits as the most likely synchronous network gate before the first interactive frame
  • For ChatGPT auth, that request resolves to GET https://chatgpt.com/backend-api/wham/usage
  • On cold starts, ModelList can also fetch remotely from:
  • https://chatgpt.com/backend-api/codex/models
  • Warm-start Wireshark summary:
  • Capture duration: 19.08s
  • First startup-correlated TLS SNI to chatgpt.com at +0.470s
  • 10.66.66.11:60589 <-> 172.64.155.209:443, start +0.3056s, duration 2.2524s, total 319 kB
  • 10.66.66.11:60547 <-> 172.64.155.209:443, start +2.4250s, duration 10.0837s, total 276 kB
  • No api.openai.com was seen in that capture
  • My current hypothesis:
  • The regression starts in 0.117.0 because the default startup path switched to the app-server TUI
  • The main warm-start latency is the first onboarding bootstrap, especially GetAccountRateLimits
  • Cold starts get even slower because ModelList can also go remote before the first interactive frame
  • Possibly relevant in some environments, but likely not the main cause on my machine:
  • #16080 increase MCP startup timeout

/cc @etraut-openai @mzeng-openai

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗