From f97d5c327538a8fe8580fa4dd9ee22c213780a59 Mon Sep 17 00:00:00 2001 From: "Adam Perry @ OpenAI" Date: Thu, 4 Jun 2026 13:07:53 -0700 Subject: [PATCH] build: use ThinLTO for release binaries (#23710) ## Why Fat LTO makes release builds substantially slower without providing enough measured runtime benefit to justify the release CI long pole. The build-profile investigation found that keeping Cargo's default release `opt-level=3` and switching from fat LTO to ThinLTO (`3/thin/1`) reduced a clean `codex-cli` release build from 2073.893 seconds to 1243.172 seconds, a 40.06% improvement. The resulting binary increased from 196.7 MiB to 211.8 MiB (+7.63%). Measured runtime changes were small: the worst image workload median was +0.86% and app-server startup was +0.31% relative to fat LTO. ThinLTO retains cross-crate optimization while avoiding most of the fat-LTO build cost. This deliberately avoids global size optimization: final-executable testing showed a substantial regression on the image request path, which is expected to become more important as image usage grows. ## What changed - Set the workspace release profile to `lto = "thin"`, retaining Cargo's default release `opt-level=3`. - Remove release and CI workflow-specific LTO overrides so release-profile builds consistently use the workspace setting. - Remove the now-unused Windows release workflow input and related diagnostic output. ## Validation - Confirmed the release profile parses with `cargo metadata --no-deps --format-version 1`. - CI validates release builds across the supported target matrix. --- .github/workflows/rust-ci-full.yml | 2 -- .github/workflows/rust-release-windows.yml | 11 ++--------- .github/workflows/rust-release.yml | 6 ------ codex-rs/Cargo.toml | 2 +- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/rust-ci-full.yml b/.github/workflows/rust-ci-full.yml index 60d508b21..50ecf2f8d 100644 --- a/.github/workflows/rust-ci-full.yml +++ b/.github/workflows/rust-ci-full.yml @@ -167,8 +167,6 @@ jobs: USE_SCCACHE: ${{ (startsWith(matrix.runner, 'windows') || (matrix.runner == 'macos-15-xlarge' && matrix.target == 'x86_64-apple-darwin')) && 'false' || 'true' }} CARGO_INCREMENTAL: "0" SCCACHE_CACHE_SIZE: 10G - # In rust-ci, representative release-profile checks use thin LTO for faster feedback. - CARGO_PROFILE_RELEASE_LTO: ${{ matrix.profile == 'release' && 'thin' || 'fat' }} strategy: fail-fast: false diff --git a/.github/workflows/rust-release-windows.yml b/.github/workflows/rust-release-windows.yml index b4c2b84c0..14d38b9db 100644 --- a/.github/workflows/rust-release-windows.yml +++ b/.github/workflows/rust-release-windows.yml @@ -2,10 +2,6 @@ name: rust-release-windows on: workflow_call: - inputs: - release-lto: - required: true - type: string # Cargo's libgit2 transport has been flaky when fetching git dependencies with # nested submodules. Prefer the system git CLI across every Cargo invocation. @@ -16,17 +12,14 @@ jobs: build-windows-binaries: name: Build Windows binaries - ${{ matrix.runner }} - ${{ matrix.target }} - ${{ matrix.bundle }} runs-on: ${{ matrix.runs_on }} - # Windows release builds can exceed an hour on fat-LTO mainline releases, - # so keep the timeout aligned with the top-level release build headroom. + # Windows release builds can exceed an hour, so keep the timeout aligned + # with the top-level release build headroom. timeout-minutes: 90 permissions: contents: read defaults: run: working-directory: codex-rs - env: - CARGO_PROFILE_RELEASE_LTO: ${{ inputs.release-lto }} - strategy: fail-fast: false matrix: diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 5e3b263ed..2888ea6ce 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -149,9 +149,6 @@ jobs: run: working-directory: codex-rs env: - # 2026-03-04: temporarily change releases to use thin LTO because - # Ubuntu ARM is timing out at 60 minutes. - CARGO_PROFILE_RELEASE_LTO: ${{ contains(github.ref_name, '-alpha') && 'thin' || 'thin' }} # Use the git CLI instead of Cargo's libgit2 path for git dependencies. # macOS release runners have intermittently failed to fetch nested # submodules through SecureTransport/libgit2, especially libwebrtc's @@ -325,7 +322,6 @@ jobs: for binary in ${{ matrix.binaries }}; do build_args+=(--bin "$binary") done - echo "CARGO_PROFILE_RELEASE_LTO: ${CARGO_PROFILE_RELEASE_LTO}" cargo build --target "$target" --release --timings "${build_args[@]}" - name: Upload Cargo timings @@ -1330,8 +1326,6 @@ jobs: if: ${{ github.event_name != 'workflow_dispatch' || inputs.release_mode == 'build_unsigned' }} needs: tag-check uses: ./.github/workflows/rust-release-windows.yml - with: - release-lto: ${{ contains(github.ref_name, '-alpha') && 'thin' || 'fat' }} secrets: inherit argument-comment-lint-release-assets: diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 15e0e2c01..5d6d11604 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -501,7 +501,7 @@ debug = "none" strip = "symbols" [profile.release] -lto = "fat" +lto = "thin" split-debuginfo = "off" # Because we bundle some of these executables with the TypeScript CLI, we # remove everything to make the binary as small as possible.