Codex CLI 0.157.0, released on Friday 25 September, turned on daemon_auto_start for every eligible interactive launch. Typing codex now starts codex app-server --managed-daemon, a process with no terminal that keeps running after you close every Codex window, copies a 374 MB package into ~/.codex/packages/app-server-daemon/, and spawns a second detached process that checks for a new release five minutes after start and every hour after that.
When the hourly check finds a new version it downloads OpenAI's installer script from chatgpt.com, runs it, and restarts the server. The server gets 60 seconds to finish whatever turns are running across every attached Codex session before the daemon force-kills it. An operator running 13 threads of build-and-test turns lasting 3 to 30 minutes watched one unattended update end all of them.
The switch that turns the daemon off exists: codex features disable daemon_auto_start, or --no-daemon on each launch. Neither appears in the config reference or the developer command list, and --no-daemon is described only in an error message. The hourly updater can be turned off in one place, a JSON file documented in a README inside the source tree.
What the release note said
The GitHub release for 0.157.0 gives the change one line: "Enabled automatic background-server startup for eligible interactive sessions, with recovery choices when server settings are incompatible." The pull request behind it, merged three days earlier, is more direct: "Promote daemon_auto_start to stable and enable it by default for eligible interactive launches. Remove its entry from /experimental." In the source the flag now reads stage: Stage::Stable, default_enabled: true.
The daemon itself is older than the default. It is the component that lets the desktop app, the mobile app and codex remote-control attach to a machine over SSH, and its README still describes it that way: "intended for Codex instances launched over SSH, including fresh developer machines that should expose app-server with remote_control enabled." The same README opens with a warning that the daemon "is experimental and its lifecycle contract may change." What 0.157.0 changed is who gets it. --no-daemon, --oss, --profile, most -c overrides, --strict-config and an elevated Windows terminal each opt a session out. A plain codex in a plain terminal opts in.
The Codex changelog at learn.chatgpt.com has no entry about it. Between 15 September and today the entries cover GPT-6 Sol and Luna, Ultrafast mode, iOS builds and a macOS security update. The config reference lists check_for_update_on_startup with the note "set to false only when updates are centrally managed" and does not list daemon_auto_start. The config JSON schema in the repository has the key as a bare boolean with no description. The enterprise page on managing updates covers an in_app_updates policy for the desktop app and says it "doesn't manage updates for mobile apps, Codex CLI, or the IDE extension."
What runs after you quit
The issue that reached the front page of Hacker News on Monday was filed on the day of the release, at 20:04 UTC, by a user on WSL2 who had installed Codex with npm. Their report lists four effects. The daemon runs in its own session with no TTY, reparented to PID 1, until codex app-server daemon stop or a reboot. It copies the whole platform package, 374 MB including codex, codex-code-mode-host and bundled copies of bwrap, zsh and rg, into ~/.codex/packages/app-server-daemon/releases/<version>/, byte-identical to what npm had just installed, and runs from the copy. A detached pid-update-loop process checks for updates. And the daemon keeps the environment of whichever session started it, so a per-invocation HTTPS_PROXY set in one terminal routes every later session's traffic.
The source confirms the schedule and supplies the mechanism. The first check waits 5 * 60 seconds; the default interval is 60 minutes. A check fetches https://chatgpt.com/codex/install.sh, or install.ps1 on Windows, runs it against the daemon's package root, and restarts the app-server if the version changed. The stop sends SIGTERM, waits shutdownGraceSeconds, default 60 with a hard cap of 300, then force-terminates. A comment in the install module states the design goal: "New daemons own their packages, regardless of how the calling CLI was installed."
That line is why package managers broke. On Arch, 0.157.0 refused to start with "this CLI has no complete local package" until users added --no-daemon. In an elevated Windows terminal it stops with "start the Windows daemon from a non-elevated terminal; shared clients must not inherit administrator privileges"; that issue has 63 comments. A WSL user on 0.155.0 found npm had updated the CLI while the already-running app-server stayed on 0.154.0, and the suggested codex app-server daemon update refused to recover it. The README says "per-client environment isolation is not provided." A new issue filed at 04:00 UTC this morning, against 0.162.1 on macOS, is titled "Daemon server leaks environment variables across sessions."
Sixty seconds
The oldest open report is from 26 August, before the default changed, from an operator who had started the daemon on purpose with codex remote-control start. They ran 13 long-lived threads whose turns executed Go build and test suites for 3 to 30 minutes. At 20:16 the updater installed 0.150.0 and restarted the server. Every attached client dropped at once and every mid-execution turn died. Their summary: "every auto-update destroys in-flight work across every thread on the host." Their second complaint: "There is also no supported way to turn auto-update off."
The current source reads an updater.autoUpdateEnabled field from ~/.codex/app-server-daemon/settings.json, default true, and the daemon README documents it alongside updateIntervalMinutes. No codex command sets either; the README says to edit the file. It also notes that "the updater uses saved network settings; CLI -c overrides do not reach it." Until 0.162.0 on 8 October, an updater that could not load its configuration fell back to a default HTTP client; the fix that week says daemon updates "must honor application network restrictions and stop when their configuration cannot be loaded." The day before, 0.161.0 enabled analytics by default for daemon-launched app servers.
A change merged on Sunday adds a restart action to a /daemon command in the TUI, with a confirmation "warning that active or queued work in other chats may be interrupted." That is the first place in the interface that states what a shared server means: your session and the one in the next tab run in one process, and a restart in either reaches both.
The disk
The Hacker News thread, 540 points and 264 comments by this morning, spent much of its time on a side effect the issue did not mention. The releases directory keeps every version. One commenter measured 12 GB of old Codex versions on their machine. Another put each binary at about 300 MB and counted 11 of them in a Bun cache. Five stable releases landed between 1 and 9 October, and each one the hourly check picks up is another copy that stays.
Claude Code does the same thing with less ceremony. It keeps old binaries in ~/.local/share/claude/versions; an issue from December showed six previous versions totalling 1.2 GB. A bot closed it in March as inactive. The reporter replied that it was still happening.
Turning it off
As of 0.162.1, released 9 October, the daemon is on by default and no OpenAI account has replied in the issue. The workaround from the original report, repeated by Hacker News commenters, is four commands. codex app-server daemon stop stops the server but leaves the updater running; the reporter found it alive 70 seconds later, which is what the pkill is for.
codex features disable daemon_auto_start
codex app-server daemon stop
pkill -f 'app-server daemon pid-update-loop'
rm -rf ~/.codex/packages/app-server-daemon
If you want the shared server but not the updates, set "updater": {"autoUpdateEnabled": false} in ~/.codex/app-server-daemon/settings.json and run codex app-server daemon restart. If you want nothing running after you close the terminal, put daemon_auto_start = false under [features] in ~/.codex/config.toml. That flag is the only switch, and the pull request that flipped it also removed it from the /experimental menu where you would have seen it.