Summary
When a Git-sourced marketplace is enabled, concurrent codex exec launches each start their own full Git clone of the same marketplace into a separate marketplace-upgrade-* staging directory.
This happened before the agent prompt was processed. A workload that spawned many short-lived, read-only codex exec --json processes amplified the behavior into dozens of concurrent HTTPS connections and several gigabytes of duplicate temporary data.
The update/materialization itself may reasonably use a staging directory for atomic replacement. The problem is that concurrent processes do not appear to share a refresh result or coordinate with a cross-process lock, and unchanged revisions are not cheaply rejected before the full clone.
Environment
- macOS on Apple Silicon
- Codex Desktop 26.721.81911, using its embedded Codex CLI
- Git-sourced marketplace configured in
~/.codex/config.toml:
[marketplaces.compound-engineering-plugin]
source_type = "git"
source = "https://github.com/EveryInc/compound-engineering-plugin.git"
ref = "main"
[plugins."compound-engineering@compound-engineering-plugin"]
enabled = true
The installed marketplace metadata had a persisted last_revision, and the on-disk marketplace clone was already present under ~/.codex/.tmp/marketplaces/compound-engineering-plugin.
Observed behavior
Each child process independently ran the equivalent of:
git clone https://github.com/EveryInc/compound-engineering-plugin.git \
~/.codex/.tmp/marketplaces/.staging/marketplace-upgrade-<random>
Observed during one incident:
- approximately 50 concurrent
git clone processes / 47 active GitHub HTTPS connections
- all clones targeted the same repository and
main ref
~/.codex/.tmp/marketplaces/.staging reached about 4.3 GB
- hundreds of
marketplace-upgrade-* directories accumulated while the parent workload was still launching new codex exec processes
After the parent workload stopped, the remaining clone children were orphaned (PPID 1) and needed manual termination before the temporary directories could be cleaned safely.
Expected behavior
For each configured Git marketplace:
- Use a lightweight ref check (for example
git ls-remote) and compare it with the stored revision before downloading the marketplace payload.
- When the ref is unchanged, reuse the existing local materialization with no full clone.
- When an update is required, use a per-marketplace cross-process lock / single-flight refresh so one process performs the staging download and other concurrent CLI launches wait for or reuse its result.
- Keep the existing atomic staging-and-swap behavior only for the one actual update.
This is especially important because codex exec is commonly launched programmatically and in parallel by test runners or orchestration tools.
Why this matters
A single accidental parallel workload can multiply one marketplace refresh into tens of identical full repository downloads, saturating bandwidth and consuming gigabytes of disk. The behavior is independent of whether the agent run itself is read-only.
Related issues
I can provide sanitized process listings and staging-directory measurements if useful.
Summary
When a Git-sourced marketplace is enabled, concurrent
codex execlaunches each start their own full Git clone of the same marketplace into a separatemarketplace-upgrade-*staging directory.This happened before the agent prompt was processed. A workload that spawned many short-lived, read-only
codex exec --jsonprocesses amplified the behavior into dozens of concurrent HTTPS connections and several gigabytes of duplicate temporary data.The update/materialization itself may reasonably use a staging directory for atomic replacement. The problem is that concurrent processes do not appear to share a refresh result or coordinate with a cross-process lock, and unchanged revisions are not cheaply rejected before the full clone.
Environment
~/.codex/config.toml:The installed marketplace metadata had a persisted
last_revision, and the on-disk marketplace clone was already present under~/.codex/.tmp/marketplaces/compound-engineering-plugin.Observed behavior
Each child process independently ran the equivalent of:
Observed during one incident:
git cloneprocesses / 47 active GitHub HTTPS connectionsmainref~/.codex/.tmp/marketplaces/.stagingreached about 4.3 GBmarketplace-upgrade-*directories accumulated while the parent workload was still launching newcodex execprocessesAfter the parent workload stopped, the remaining clone children were orphaned (PPID 1) and needed manual termination before the temporary directories could be cleaned safely.
Expected behavior
For each configured Git marketplace:
git ls-remote) and compare it with the stored revision before downloading the marketplace payload.This is especially important because
codex execis commonly launched programmatically and in parallel by test runners or orchestration tools.Why this matters
A single accidental parallel workload can multiply one marketplace refresh into tens of identical full repository downloads, saturating bandwidth and consuming gigabytes of disk. The behavior is independent of whether the agent run itself is read-only.
Related issues
plugin/list— no TTL, no content check, ~65 GB/day of disk writes #35401 reports repeated plugin-catalog refreshes/writes without TTL or content comparison. This report is specifically about the Git marketplace upgrade/materialization path and concurrent full clones.marketplace_upgraderefresh path.I can provide sanitized process listings and staging-directory measurements if useful.