Skip to content

Windows Desktop WSL mode should split persistent CODEX_HOME from native WSL runtime cache #26985

Closed

Description

@pussikill

What version of the Codex App are you using (From “About Codex” dialog)?

OpenAI.Codex 26.602.4764.0
Package: OpenAI.Codex_26.602.4764.0_x64__2p2nqsd0c76g0

What subscription do you have?

Pro

What platform is your computer?

Microsoft Windows NT 10.0.26100.0 x64
WSL2 Ubuntu, app-server launched from Codex Desktop WSL mode.

What issue are you seeing?

This is a focused proposal/bug report for the Windows Desktop + WSL runtime-cache behavior.

Several open issues describe overlapping symptoms around Windows Desktop WSL mode: config/home ambiguity, very slow plugin/skill discovery, stale arg0 temp paths, WSL UNC sandbox ACL failures, and heavy /mnt/c filesystem scans.

Related issues:
#22759, #13762, #18506, #24101, #24268, #25317, #25745, #25747, #26149, #26766, #25715, #16970, #26904.

The underlying problem appears to be that Desktop WSL mode currently overloads CODEX_HOME for both:

  1. persistent Desktop/user state: auth, config, sessions, sqlite/log state;
  2. runtime-heavy WSL data: plugin cache, marketplace temp dirs, bundled/system skills cache, arg0 temp helpers.

For Desktop users, moving the entire CODEX_HOME to native WSL would be risky because it can split auth/config/session state and may force re-authentication. But keeping all runtime-heavy data under /mnt/c/Users/.../.codex makes plugin/skill discovery very slow in WSL because the Linux app-server walks thousands of files through drvfs.

A more stable behavior would be:

  • keep persistent Desktop state under the Windows-backed CODEX_HOME;
  • move runtime-heavy WSL cache/temp data to native WSL storage, e.g. ~/.codex/runtime/wsl/<distro>;
  • expose/warn about the distinction so users understand whether auth/config is shared with Desktop or native to WSL;
  • provide an explicit opt-in for users who want fully native WSL CODEX_HOME.

I have a working branch implementing this approach for review/reference:

main...pussikill:codex/wsl-desktop-runtime-cache

Note: I understand external PRs are by invitation only per docs/contributing.md. I am opening this issue to share analysis, reproduction data, and a concrete implementation direction for maintainers to evaluate.

What steps can reproduce the bug?

  1. Use Codex Desktop on Windows with WSL mode enabled.
  2. Ensure Desktop launches the Linux app-server through WSL while keeping:
    • CODEX_HOME=/mnt/c/Users/<user>/.codex
    • HOME=/home/<wsl-user>
    • CODEX_SQLITE_HOME=/home/<wsl-user>/.codex/sqlite
  3. Use plugins/skills so plugin and skill discovery touches the runtime plugin cache.
  4. Trigger app-server RPCs:
    • initialize
    • config/read
    • plugin/list
    • skills/list
    • skills/list with forceReload=true
  5. Compare the current store bundle behavior with a build that keeps Desktop persistent state on Windows but routes WSL runtime cache to native WSL storage.

For local validation, I used a benchmark harness that launches the app-server over stdio and measures these RPCs.

Clean isolated benchmark command:

python3 bench-wsl-desktop-app-server.py --isolated --clean --iterations 10

Hot isolated benchmark command:

python3 bench-wsl-desktop-app-server.py --isolated --iterations 8

Real non-isolated sanity check:

python3 -u bench-wsl-desktop-app-server.py --iterations 1 --verbose --request-timeout 120

What is the expected behavior?

Windows Desktop WSL mode should preserve Desktop auth/config/session state without forcing users to sign in again, but should not store or repeatedly scan heavy WSL runtime caches through /mnt/c.

Expected split:

  • persistent state/auth/config/sessions: Windows-backed Desktop CODEX_HOME;
  • WSL runtime plugin/skill/temp cache: native WSL filesystem;
  • clear warning or UI copy explaining the distinction;
  • explicit opt-in for users who want native WSL CODEX_HOME instead.

Additional information

Isolated multi-run benchmarks showed the improvement without touching the real user profile.

Cold median, 10 runs:

  • initialize: 414.3ms -> 286.3ms
  • skills/list: 690.8ms -> 99.0ms
  • skills/list:forceReload: 714.9ms -> 101.0ms

Warm median, 10 runs:

  • initialize: 427.3ms -> 233.4ms
  • skills/list: 711.7ms -> 94.9ms
  • skills/list:forceReload: 718.4ms -> 94.8ms

Hot-path isolated median, 8 runs:

  • initialize: 400.6ms -> 216.2ms
  • skills/list: 630.2ms -> 95.3ms
  • skills/list:forceReload: 669.0ms -> 95.0ms

I also ran a non-isolated sanity check on the real local environment. I checked the filesystem footprint carefully to avoid comparing unrelated state.

The whole Windows CODEX_HOME size is not the right primary metric because it also contains persistent auth/session/config/log state. The comparable footprint is the plugin temp runtime tree used by plugin/skill discovery.

Comparable plugin temp tree:

  • store path: /mnt/c/Users/xdev/.codex/.tmp/plugins

    • 4,909 files
    • 2,564 dirs
    • 59,447,140 bytes
  • patched path: /home/xdev/.codex/runtime/wsl/Ubuntu/.tmp/plugins

    • 4,908 files
    • 2,562 dirs
    • 58,713,015 bytes

The remaining differences are mostly git metadata/refs, so this is effectively the same runtime plugin tree served from different filesystems.

The RPC result size was also the same:

  • config/read: 3 layers
  • plugin/list: 2 marketplaces
  • skills/list: 1 skill

Non-isolated single-run timing on the real local environment:

  • initialize: store 547.8ms -> patched 219.9ms
  • plugin/list: store 1125.0ms -> patched 479.4ms
  • skills/list: store 28816.7ms -> patched 374.0ms
  • skills/list:forceReload: store 19196.9ms -> patched 602.2ms

This suggests the bottleneck is not different returned data or a smaller cache. The returned data is the same and the comparable runtime tree is nearly identical. The difference is that the current store bundle walks that tree through /mnt/c, while the patched build serves the heavy runtime plugin/skill cache from native WSL storage.

Implementation direction in the branch:

  • add a WSL-aware runtime cache home derived from CODEX_HOME;
  • keep persistent Desktop state/auth/config in Windows CODEX_HOME;
  • route plugin/marketplace/system-skill runtime cache/temp paths to native WSL runtime cache;
  • keep user skills persistent;
  • add WSL-aware arg0 temp namespacing and .pid guard;
  • skip unsupported Windows ACL refresh for WSL UNC paths;
  • add an explicit warning and opt-in env for native WSL CODEX_HOME.

Validation already run locally:

just fmt
TMPDIR=/home/xdev/tmp/codex-clean-test-tmp cargo test -p codex-utils-home-dir -p codex-core-plugins -p codex-core-skills -p codex-arg0 -p codex-windows-sandbox --lib
TMPDIR=/home/xdev/tmp/codex-clean-test-tmp cargo test -p codex-app-server desktop_wsl_windows_codex_home_warning --lib
TMPDIR=/home/xdev/tmp/codex-clean-test-tmp cargo test -p codex-app-server config_read_returns_effective_and_layers --test all
TMPDIR=/home/xdev/tmp/codex-clean-test-tmp cargo test -p codex-app-server skills_list_loads_remote_installed_plugin_skills_from_cache --test all
cargo +1.95.0-x86_64-unknown-linux-gnu test --target x86_64-pc-windows-gnu -p codex-utils-home-dir -p codex-arg0 -p codex-windows-sandbox --lib

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    app-serverIssues involving app server protocol or interfaces
    skillsIssues related to skills
    on Jun 8, 2026
  2. laverya commented on Jun 8, 2026

    @laverya

    I couldn't see the code easily from your link, so here's a better one for others: main...pussikill:codex:codex/wsl-desktop-runtime-cache

  3. pussikill commented on Jun 8, 2026

    @pussikill
    Author

    Thanks for checking. I verified the compare through the GitHub API; the canonical URL it returns is:

    main...pussikill:codex/wsl-desktop-runtime-cache

    I updated the issue body to use that exact form.

  4. MisterRound commented on Jun 10, 2026

    @MisterRound

    This issue's split-home direction matches the local CUA/arg0 evidence very closely.

    Additional data point from a Windows Desktop + WSL setup:

    • Keeping persistent Desktop state under %USERPROFILE%\.codex is still useful for auth/config/session continuity.
    • But runtime-heavy and runtime-family-specific state sharing the same home creates failure modes beyond performance:
      • WSL/Linux arg0 symlink helpers and Windows .bat helpers can land under the same %USERPROFILE%\.codex\tmp\arg0 root.
      • Windows-native node_repl.exe -> codex.exe app-server --listen stdio:// sidecars for CUA/browser-use can create .bat helpers there.
      • A live WSL app-server/thread can then be pinned to a deleted codex-arg0<hash> helper dir and fail before /bin/bash starts with Io(Os { code: 2 }).

    The local workaround that made CUA pass uses the same conceptual split:

    • persistent Desktop home remains %USERPROFILE%\.codex;
    • Windows node_repl sidecar runs from an isolated Windows home:
    %USERPROFILE%\.codex\chrome-runtime-home
    
    • the wrapper discovers and forwards:
    SKY_CUA_NATIVE_PIPE_DIRECTORY=\\.\pipe\codex-computer-use-<uuid>
    
    • shared %USERPROFILE%\.codex\tmp\arg0 stays WSL/Linux-only;
    • Windows .bat helpers are confined to the isolated runtime home.

    With that shape, current local smokes passed:

    • computer-use-client.mjs bootstrap;
    • sky.list_apps();
    • window state capture;
    • Calculator action proof;
    • 12-second hold-open proof;
    • Photoshop clean-document UI-only drawing/text proof;
    • clean sky.close();
    • no shared-root .bat pollution.

    So I would add CUA/browser-use sidecar isolation to the acceptance criteria for this issue:

    1. Desktop WSL mode keeps persistent state/auth/config/sessions in the Windows-backed Desktop home.
    2. Runtime-heavy WSL cache/temp state is WSL-native where possible.
    3. arg0 helpers are runtime-family namespaced or otherwise protected from cross-runtime janitors.
    4. Product-generated CUA/browser-use Windows sidecars use an isolated Windows runtime home, not the shared WSL Desktop home.
    5. The CUA native-pipe env (SKY_CUA_NATIVE_PIPE_DIRECTORY) survives that isolation.
    6. After a real CUA action smoke, shared %USERPROFILE%\.codex\tmp\arg0 remains WSL/Linux-only.
  5. carakamoij commented on Jun 16, 2026

    @carakamoij

    Version 26.609.71450 • Released 16 Jun 2026 seems to have fixed this issue finally.

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

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingperformanceskillsIssues related to skillswindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions