Release builds block `codex exec` exit ~900 ms flushing Statsig OTLP metrics after the turn completes
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of Codex CLI is running?
codex-cli 0.146.0
What subscription do you have?
Plus
Which model were you using?
No response
What platform is your computer?
macOS 26.5 (Apple Silicon); expected on all platforms since the exporter is not OS-gated
What terminal emulator and version are you using (if applicable)?
iTerm2
Codex doctor report
What issue are you seeing?
A release-profile codex enables the Statsig OTLP metrics exporter
(codex-rs/otel/src/config.rs defaults to OtelExporter::Statsig; it is disabled
under cfg!(debug_assertions), which is why debug builds never show this).
During shutdown the exporter flushes over HTTPS to ab.chatgpt.com, holding
process exit long after the turn is finished.
Measured on macOS (Apple Silicon), release build, mock model provider so model
latency is excluded, 30 runs, p50:
| configuration | turn.completed | process exit | shutdown tail |
|---|---|---|---|
| default | 136.1 ms | 1,046.2 ms | 910.1 ms |
| otel.metrics_exporter = "none" | 111.5 ms | 115.9 ms | 4.4 ms |
Interactive sessions pay this once. codex exec one-shots and SDK-style
automation that spawns a process per turn pay it on every turn: ten short
turns take ~9.9 s wall clock with the default config and ~0.7 s with the
exporter off.
What steps can reproduce the bug?
- Build codex with --release (or use a released binary).
- Run
codex exec "say hi"against a mock/fast provider and record the
timestamp of theturn.completedevent vs process exit. - Add
[otel] metrics_exporter = "none"to config.toml and repeat. - The gap between answer-complete and exit drops from ~910 ms to ~5 ms.
What is the expected behavior?
Process exit should not be held for a blocking network flush after the answer
is complete. Options: flush asynchronously, bound the shutdown flush with a
short deadline (e.g. 100 ms), or start the flush at turn.completed instead of
at exit.
Additional information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/otel/src/config.rs and the release-only Statsig exporter configuration, then reproduce the issue through the codex exec entry point using a mock or fast provider. Compare the turn.completed timestamp with process exit under the default configuration and with metrics_exporter = "none"; done means the release build no longer holds exit for roughly 900 ms after the turn completes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100