Codex CLI history: find, resume and read old sessions

Where Codex CLI keeps session history, how codex resume and codex fork find it, jq one-liners for rollout files, and viewing it all in VS Code.

Yash Agarwal

Builds Claude Code and Codex Assist

Published
Updated
Data as of
Reading time
9 min read
A terminal listing dated session files beside an editor that shows one of those sessions as a readable conversation with a diff.

TL;DR: Codex CLI saves every session as a JSONL "rollout" file under ~/.codex/sessions/YYYY/MM/DD/. To continue one, run codex resume (current folder), codex resume --all (every folder) or codex resume --last. To branch without touching the original, use codex fork. To read a session without Codex, a few jq commands below will list sessions, print your prompts and show which files changed. To browse, search and diff all of it inside VS Code, install CCAssist.

Where is my Codex CLI history stored?#

Codex CLI writes one file per session to ~/.codex/sessions/, grouped into year, month and day folders. The file is a rollout: a JSONL file (one JSON object per line) that holds the whole session in order, including your prompts, the model's replies, tool calls, command output and token counts. If you set the CODEX_HOME environment variable, everything below lives under that folder instead of ~/.codex.

Anatomy of a Codex rollout path: ~/.codex is Codex home, 2026/09/30 is the local date the session started, the rollout name carries the local start time and the thread ID, and a second file with _<rollout-id> continues the same thread. Four cards list session_index.jsonl (thread names), history.jsonl (typed prompts), archived_sessions (archived rollouts) and state_5.sqlite (the thread index the resume picker reads).
Paths from the openai/codex source (rust-v0.159.2) and a real ~/.codex folder, checked 1 October 2026.

Here is what each file in ~/.codex is for:

PathWhat it holdsUseful for
sessions/YYYY/MM/DD/rollout-<time>-<thread-id>.jsonlThe full session, line by lineReading or searching a session
session_index.jsonlid, thread_name, updated_at, one line per rename; the newest line winsMapping a name back to a thread ID
history.jsonlEach prompt you typed: session_id, text, tsFinding which session a prompt was in
archived_sessions/Rollouts moved here by codex archiveRecovering a session that left the resume list
state_5.sqliteA threads table, one row per threadWhat the resume picker reads

A few details matter once you start looking by hand:

  • The folder date and file-name time use your local clock. On my machine (UTC+5:30), a session named rollout-2026-09-30T00-53-49-… records 2026-09-29T19:23:49Z as its start time inside the file. A late-night session can sit in the next day's folder.
  • One thread can span two files. A file named rollout-<time>-<thread-id>_<rollout-id>.jsonl continues the thread whose ID comes before the underscore. The Codex source uses this name when a thread gets a new rollout ID. I had 15 such files out of 1,590.
  • Sub-agents get their own rollout files. When Codex spawns a sub-agent, the child writes a separate rollout whose first line names the parent under source.subagent.thread_spawn.parent_thread_id. In my last 60 rollout files, 23 were sub-agents.
  • history.jsonl is only your prompts. It never holds replies, and history.max_bytes in config.toml makes Codex drop its oldest entries once the file passes that size (config source).

For scale: on 1 October 2026 my ~/.codex/sessions held 1,590 rollout files from December 2025 to September 2026, 1.6 GB in total. The files are plain text until something deletes them, so old sessions stay readable. Claude Code works differently and cleans up its transcripts after 30 days by default. Where Claude Code stores conversations covers that side.

Resume a Codex session with codex resume#

codex resume is the built-in way back into an old session. It opens a picker of recent sessions started in the current folder; choose one and Codex reloads the transcript and continues the same thread. These are the forms in the Codex CLI command reference and in codex resume --help (Codex CLI 0.159.2 was the latest npm release on 1 October 2026):

CommandWhat it does
codex resumePicker of recent sessions from the current folder
codex resume --allPicker across every folder, with a working-folder column
codex resume --lastSkips the picker and reopens the most recent session here
codex resume <id or name>Reopens one session by thread ID (a UUID) or by name
codex resume --include-non-interactiveAlso lists sessions started with codex exec
codex exec resume --last "next step"Continues a non-interactive run with a follow-up prompt
/resume inside CodexOpens the same picker without leaving the TUI

When you quit, Codex prints the exact command to get back: To continue this session, run: codex resume <id>. Inside a running session, /status shows the session ID. Some guides suggest /rollout to print the file path; in the current source that command only exists in debug builds, so a normal install won't show it.

If the session started in a different folder from where you are now, Codex asks which folder to use. Set tui.resume_cwd to "current" or "session" in config.toml to skip that question.

Why is a session missing from the picker?#

Work through these in order:

SymptomLikely causeFix
Session from another project is missingThe picker filters by current foldercodex resume --all
A codex exec run is missingNon-interactive sessions are hidden--include-non-interactive
Session vanished after cleanupIt was archivedcodex unarchive <id or name>
You copied a rollout file in by hand and it doesn't showThe picker reads the threads table in state_5.sqlite, not the folderResume it by ID, or open it with a viewer that reads the files
You only remember what it changedThe picker shows names and previews, not contentsSearch the files (below)

Fork a session instead of continuing it#

codex fork starts a new thread from a copy of an old one. The original rollout stays as it was, so you can try a different approach from the same starting point and still go back. It takes the same --last and --all flags and a thread ID. Inside Codex, /fork forks the chat you are in.

Two related commands tidy the list rather than branch it. codex archive <id or name> moves a session's rollout into ~/.codex/archived_sessions/ and out of the resume list; codex unarchive brings it back. codex delete <id or name> removes a session permanently, so copy the rollout somewhere first if you might want it later.

Read Codex rollout files with jq#

You don't need Codex running to read history. Every line in a rollout has a type and a payload, and the first line is always session_meta.

Rollout line types: session_meta on line 1 with session id, cwd, cli_version, git and source; turn_context per turn; response_item for messages, reasoning and tool calls; event_msg for token counts, task start and end and completed items; compacted for compaction summaries; token_usage_record for newer bookkeeping. A bar chart of one real 222-line session shows 49 item_completed events, 37 token_usage_record lines, 37 token_count events, 35 tool calls, 35 tool outputs, 10 reasoning items, 8 messages and 11 other lines.
Line types from the openai/codex RolloutItem enum (rust-v0.159.2). Counts are from one local session written by Codex 0.159.0; other sessions differ.

I tested these commands on 1 October 2026 against a sample of rollouts on my machine written by Codex 0.80 to 0.159. Replace FILE with a rollout path.

List your 10 newest sessions with their folder and thread ID:

find ~/.codex/sessions -name 'rollout-*.jsonl' | sort | tail -n 10 |
while read -r f; do
  head -n 1 "$f" | jq -r '[.payload.timestamp, .payload.cwd, .payload.id] | @tsv'
done

Sorting by path works because the folders and file names start with the date. The thread ID in the last column is what codex resume and codex fork accept.

Print the prompts you typed in one session:

jq -r 'select(.type == "event_msg") | .payload
  | if .type == "user_message" then .message
    elif .type == "item_completed" and .item.type == "UserMessage"
      then (.item.content[]?.text // empty)
    else empty end' FILE

Codex has recorded user messages in both shapes over time, so the filter checks for each. Reading response_item messages with role user also works, but those include the instructions and environment context Codex injects at the start.

List the files a session changed:

jq -r '
  (select(.payload.item.type? == "FileChange") | .payload.item.changes | keys[]),
  (select(.payload.name? == "apply_patch")
    | (.payload.input // .payload.arguments // "")
    | capture("\\*\\*\\* (Add|Update|Delete) File: (?<f>[^\\n]+)"; "g").f)
' FILE | sort -u

Newer rollouts record edits as FileChange items; older ones only keep the apply_patch call, so the filter reads both. It lists files edited through Codex's patch tool. Files changed by a shell command (a sed -i, a heredoc) show up only as commands, not as file changes.

Show the session's running token total:

jq -c 'select(.payload.type == "token_count")
  | .payload.info.total_token_usage' FILE | tail -n 1

Find every session that mentions a word:

grep -rli --include='rollout-*.jsonl' 'stripe webhook' ~/.codex/sessions

This matches tool output as well as conversation text, which is usually what you want when you remember an error message but not the prompt.

Browse Codex history in VS Code with CCAssist#

The CLI and jq answer "take me back to that session". They get slow when the question is "which session changed this file last Tuesday, and what exactly did it change?" CCAssist (Claude Code and Codex Assist, version 0.7.5 on the VS Code Marketplace as of 1 October 2026) reads the same ~/.codex/sessions files and shows them in a VS Code sidebar next to your Claude Code, Cursor, Grok and OpenCode sessions.

What it does with Codex sessions:

  • Session list per project. Sessions are grouped by the folder they ran in, titled from session_index.jsonl where a name exists, with a source badge so Codex and Claude Code rows don't blur together.
  • Readable transcripts. Prompts, replies, reasoning, commands and their output, images and Codex visualizations render as a conversation instead of JSON. Sub-agents appear in an agent bar inside the parent session, and threads split across two rollout files show as one session.
  • Search across all sessions from one box, Codex and Claude Code together.
  • Diffs. Files changed through Codex's patch tool open as before/after diffs, and you can jump from a file to the session that edited it.
  • Resume and fork. A Resume action runs codex resume <id> in a VS Code terminal (or opens the session in the Codex app or extension, if you set that as the target). Fork runs codex fork <id>. Both work for sessions the CLI picker no longer lists, as long as the rollout file still exists.
  • Convert to Claude Code format, or from Claude Code to Codex, to continue the same work in the other CLI.
  • Usage and cost. Codex tokens and estimated costs appear in the same dashboard as Claude Code. Costs are estimates computed from token counts and published API prices; ChatGPT-plan users don't pay per token. The usage tracker page explains the numbers.

What is free and what needs Pro (checked in the extension source on 1 October 2026):

FeatureFreePro
Browse and read Codex sessionsYesYes
SearchAll sessions; results older than 3 days are blurredFull results
DiffsChanges made the same dayAny date
Resume, and codex fork in a terminalYesYes
Fork from a chosen messageNoYes
Claude ⇄ Codex conversion, fork with summary3 eachUnlimited
Keep a backup copy of a session3 sessionsUnlimited
Usage dashboardLast 7 daysFull history

Pricing is on the upgrade page.

What it does not do: it reads ~/.codex/sessions (plus any folders you add under the claude-history.codexChatDirectories setting), not CODEX_HOME or ~/.codex/archived_sessions, so archived or relocated sessions need that setting or codex unarchive. It can't show a session whose rollout file was deleted. Transcripts stay on your machine; nothing is uploaded unless you turn on the optional community features.

If you'd rather have a free, focused browser, Codex History Viewer by hiztam browses, searches, tags and exports Codex CLI and Claude Code sessions (7,791 Marketplace installs, 4.9 from 8 ratings, version 2.15.0, read 1 October 2026). Pick it if you don't need diffs or usage numbers. For Claude Code's side of the same problem, see how to view Claude Code chat history.

How we checked#

  • Codex CLI: commands and flags from codex resume --help, codex fork --help (0.144.6 installed locally), the developer command reference and the openai/codex source at the rust-v0.159.2 release (29 September 2026), read 1 October 2026.
  • File layout and counts: one real ~/.codex folder, checked 1 October 2026. Only structure, counts and JSON keys were read for this post; no prompts or code are shown.
  • CCAssist: features and Free/Pro limits checked against the extension source and changelog for version 0.7.5, the Marketplace release on 1 October 2026.
  • Limits: Codex changes its rollout format often. New line types appear every few releases, so treat the jq filters as a starting point and check jq -c 'keys' FILE if one returns nothing.

Install CCAssist from the VS Code Marketplace (or Open VSX for Cursor and Windsurf) and your Codex sessions appear in the sidebar, grouped by project, with diffs and a Resume button on each one.

Frequently asked questions

Where does Codex CLI store conversation history?
Each session is a JSONL rollout file under ~/.codex/sessions/YYYY/MM/DD/, named rollout-<start time>-<thread id>.jsonl. Thread names are in ~/.codex/session_index.jsonl and your typed prompts in ~/.codex/history.jsonl. If CODEX_HOME is set, look there instead of ~/.codex.
How do I resume a previous Codex CLI session?
Run codex resume to pick from recent sessions in the current folder, codex resume --all to see every folder, codex resume --last for the most recent one, or codex resume <thread id> for a specific session. Inside Codex, /resume opens the same picker.
Why is my Codex session missing from the resume picker?
The picker only shows the current folder unless you pass --all, hides non-interactive codex exec runs unless you pass --include-non-interactive, and hides archived sessions. It also reads a thread index in state_5.sqlite, so a rollout file copied into the folder by hand may not appear.
What is the difference between codex resume and codex fork?
codex resume continues the same thread and appends to its rollout file. codex fork starts a new thread from a copy of an old one, so the original session stays unchanged.

codexhistorydiffs