The root
Everything lives under $CODEX_HOME, which defaults to ~/.codex. Sessions sit in sessions/ beneath it.
Codex CLI guide: session storage
Codex calls a stored session a rollout, and it files rollouts by date rather than by project. That one decision changes how you find them: you cannot compute the path from a project directory, so everything resolves by session id instead.
OpenAI
Everything lives under $CODEX_HOME, which defaults to ~/.codex. Sessions sit in sessions/ beneath it.
A rollout is written to sessions/YYYY/MM/DD/rollout-<local-time>-<uuid>.jsonl. The date is the day the session started, in local time, so a session that runs past midnight stays filed under the day it began.
Older rollouts are compressed in place to .jsonl.zst. Anything reading the history has to handle both extensions, which is the single most common reason a homegrown Codex log reader stops finding old sessions.
Because the tree is keyed on date and not on the working directory, there is no way to compute where a project stores its sessions. You resolve by id, which in practice means scanning the tree or reading the index.
Codex keeps session_index.jsonl and history.jsonl at the root of the home directory. The index is what makes a lookup by id cheap instead of a full walk.
Compare
| Claude Code | Codex CLI | Grok CLI | |
|---|---|---|---|
| Root directory | ~/.claude/projects | $CODEX_HOME/sessions | $GROK_HOME/sessions |
| One session is | One .jsonl file | One .jsonl rollout file | A directory of files |
| Grouped by | Slugged project path | Date, as YYYY/MM/DD | Slugged project path |
| Path from project + id | Derivable | Not derivable, resolve by id | Derivable |
| Old sessions | Left as plain .jsonl | Compressed to .jsonl.zst | Left as plain files |
| Built-in index | None, scan the tree | session_index.jsonl | summary.json per session |
Termdeck drives all three from one console, so the differences above stop being three separate habits to remember.
FAQ
Codex files rollouts by date, not by working directory. The path contains the day the session started and a UUID, and nothing about the project, so a session is found by id or by scanning the dated tree.
It is an older rollout that Codex has compressed with zstandard. The content is the same line-delimited JSON, just compressed. Any reader that only looks for .jsonl will silently miss every archived session.
Yes. Set the CODEX_HOME environment variable and Codex reads and writes there instead of the default. Move the existing directory with it or the previous history will look like it vanished.
Yes, inside the file rather than in its path. That is how a tool can group rollouts by project even though the directory tree gives no hint.
Claude Code, Codex and Grok in one browser console