Resume a Claude Code Session: --continue, --resume, /resume, and Where Sessions Are Kept
📅 October 13, 2026 · ⏱️ 13 min read
To pick up a Claude Code conversation where you left it, run claude -c (long form claude --continue) in the same directory: it reopens the most recent conversation in that directory. To choose a different one, run claude -r (long form --resume) with no argument for a session picker, or claude --resume <session-id> or claude --resume <name> to go straight to it. Inside a running session, /resume opens the same picker.
On this machine claude --version printed 2.1.296 (Claude Code), and claude --help describes the two flags like this:
claude --version; echo "exit $?"
2.1.296 (Claude Code)
exit 0
claude --help | grep -A1 -e '-c, --continue'; echo "exit ${PIPESTATUS[0]}"
-c, --continue Continue the most recent conversation in
the current directory
exit 0
claude --help | grep -A2 -e '-r, --resume' -e '--fork-session'; echo "exit ${PIPESTATUS[0]}"
--fork-session When resuming, create a new session ID
instead of reusing the original (use
with --resume or --continue)
--
-r, --resume [value] Resume a conversation by session ID, or
open interactive picker with optional
search term
exit 0
The help text says --resume takes a session ID or a search term. The CLI reference says more: “Resume a specific session by ID or name, or show an interactive picker to choose a session.” and “In place of an ID, you can pass the absolute path to a session’s .jsonl transcript file.” So on 2.1.296 a name, an ID and a transcript path all work, according to the docs, even though --help mentions only the ID. The same reference warns that “claude --help does not list every flag, so a flag’s absence from --help does not mean it is unavailable.”
These three are the everyday forms. Each one starts an interactive session, so none of them was run for this page:
claude --continue
claude --resume
claude --resume auth-refactor
Not run here: each line starts an interactive Claude Code session.
The three ways back, from the docs
The sessions page defines a session as a saved conversation, and it is saved as you go: “Sessions are saved continuously to local transcript files as you work, so you can return to one after exiting or running /clear.” Its table of entry points:
| Command | What it does (quoted) |
|---|---|
claude --continue | ”Reopens the most recent session in the current directory” |
claude --resume | ”Opens the session picker” |
claude --resume <name> | ”Resumes the named session directly” |
/resume | ”Switches to a different session from inside an active session” |
The commands list gives /resume an optional argument: “Resume a conversation by ID or name, or open the session picker.” So /resume auth-refactor inside a session jumps straight to a session with that name.
Names are what make --resume pleasant to type. Set one at startup with claude -n auth-refactor (long form --name) or mid-session with /rename. If you never name a session, “Claude Code generates a session title for it”, and that title also works as a resume handle. The short default label you see in some listings does not: “The default isn’t a resume handle. If you pass it to claude --resume or /resume, Claude Code doesn’t find the session.” When a name matches more than one session, claude --resume <name> “Opens the session picker with the name pre-filled as a search term”, while /resume <name> “Reports an error; run /resume with no argument to open the session picker”.
In the picker, Space previews a session, Ctrl+R renames the highlighted one, Ctrl+B filters to the current git branch, Ctrl+W widens to every worktree of the repository and Ctrl+A widens to every project on the machine.
How a session is tied to its directory
“A session is a saved conversation tied to a project directory.” and “Claude Code stores sessions per project directory.” That is why claude --continue only looks at the directory you run it in. Run claude -c from the directory you started the session in.
Resuming by ID is less strict. “You can run claude --resume <session-id> from any directory”, and the CLI reference gives the search order: “When you pass a session ID, Claude Code searches the current project directory and its git worktrees, then every other project on this machine. Before v2.1.223, the ID search covered only the current project directory and its git worktrees.” If nothing matches, Claude Code “reports No conversation found with session ID: <session-id>.”
Picking a session from somewhere else in the picker behaves differently depending on where it lives: “When you select a session from an unrelated project, Claude Code copies a cd and resume command to your clipboard instead.” To move a session for good, /cd does it: “Moving a session with /cd relocates it to the new directory’s project storage, so it appears in that directory’s picker afterward.”
What comes back is the “Conversation history: the full history, including tool calls and results.” Some launch flags do not come back: “If the session depended on --mcp-config, --settings, --plugin-dir, --fallback-model, or directories added with --add-dir, pass them again when you resume”. Settings files are fine: “The standard settings files, such as settings.json and settings.local.json, are re-read at launch, so configuration that lives in them doesn’t need to be passed again.”
Continue in a copy: --fork-session
--fork-session is documented, and it is in --help above: “When resuming, create a new session ID instead of reusing the original (use with --resume or --continue)”. The branching section shows it with --continue:
claude --continue --fork-session
Not run here: it starts an interactive Claude Code session.
Not run here for the same reason as the others. Inside a session the equivalent is /branch. The reason to fork rather than simply resume twice: “If you resume the same session in two terminals without forking, messages from both interleave into one transcript.” One cost: “If you fork into a separate process with --fork-session, the new process starts without them and you re-approve there”, where “them” means the permissions you allowed for the session only.
Where transcripts are stored, and how long they are kept
From the sessions page: “By default, Claude Code stores transcripts as JSONL at ~/.claude/projects/<project>/<session-id>.jsonl, where <project> is your working directory path with non-alphanumeric characters replaced by -.” Long paths get shortened: “For a working directory whose converted name exceeds 200 characters, Claude Code truncates the name to 200 characters and appends a hash of the full path”. Do not build tools on the file contents: “The entry format is internal to Claude Code and changes between versions, so scripts that parse these files directly can break on any release.”
The whole tree moves if you set CLAUDE_CONFIG_DIR. The environment variables page says it will “Override the configuration directory (default: ~/.claude). All settings, session history, and plugins are stored under this path.” CLAUDE_CODE_PROJECT_DIR_NAME lets you choose the <project> part yourself, and the docs say to set it together with CLAUDE_CONFIG_DIR.
How long they last is cleanupPeriodDays. The settings reference defines it: “Set how many days Claude Code keeps session transcripts and other application data before deleting them. Claude Code runs the deletion as a background sweep after a session starts, as long as it can safely determine the retention period. The sweep deletes transcripts without showing a message, so a session you haven’t used for longer than the retention period no longer appears in the /resume picker.” The default is 30 and the minimum is 1. For a long history, the docs suggest a big number rather than zero: “Setting 0 fails validation, so pick a large value such as 3650 for long retention.” In ~/.claude/settings.json:
{
"cleanupPeriodDays": 3650
}
Keep in mind what you are keeping: “Transcripts and history are not encrypted at rest. OS file permissions are the only protection.” That is from the .claude directory page, which also lists everything else the same sweep deletes.
Resuming on another machine
The docs do not describe carrying a session from one computer to another by copying its transcript, and I have not tested that, so this page does not suggest it. What they do say points the other way. Resuming by ID searches “Every other project on this machine”, and the cloud page draws the line explicitly: “--teleport is distinct from --resume. --resume reopens a conversation from this machine’s local history and doesn’t list cloud sessions; --teleport pulls a cloud session and its branch.” (from Claude Code on the web).
The documented way to keep working on a local session from another device is Remote Control, which leaves the session running where it is: “Remote Control connects claude.ai/code or the Claude app for iOS and Android to a Claude Code session running on your machine. Start a task at your desk, then pick it up from your phone on the couch or a browser on another computer.”
The transcript directory name, worked out on a scratch project
The naming rule above is simple enough to compute. Everything from here on ran in a scratch directory on this machine with CLAUDE_CONFIG_DIR and HOME pointed inside it, so the commands below never saw the machine’s real Claude Code data. This applies the documented rule (every non-alphanumeric character becomes -) to the scratch project’s path:
mkdir proj
printf '%s\n' "$PWD/proj" | sed 's/[^A-Za-z0-9]/-/g'
-home-loopdev-dankdev-node-modules--scratch-resume-proj
Note the doubled dash in node-modules--scratch: the / and the . each became one -, and the underscore in node_modules became a dash too. The purge run further down shows that Claude Code 2.1.296 uses this exact name.
Resuming a headless claude -p run by its session ID
Runs started with -p are left out of the shortcuts: “Claude Code leaves sessions created with claude -p or the Agent SDK out of the session picker and out of claude --continue. You can still resume one by passing its session ID to claude --resume <session-id>.” The headless page shows how to capture that ID from --output-format json and send a follow-up:
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
Not run here: claude -p sends the prompt to a model, and nothing on this page calls one.
Per that page, “You can run the two commands from different directories: Claude Code finds the session by its ID in any project on this machine.” The -p form of continue is the exception to the skip rule: “When you run claude -p --continue, Claude Code includes -p, SDK, and /loop sessions.”
If you never want a scripted run to be resumable, there is a flag for that, and --help describes it like this:
claude --help | grep -A2 -e '--no-session-persistence'; echo "exit ${PIPESTATUS[0]}"
--no-session-persistence Disable session persistence - sessions
will not be saved to disk and cannot be
resumed (only works with --print)
exit 0
The same effect in any mode comes from CLAUDE_CODE_SKIP_PROMPT_HISTORY, which the docs describe as: “Set to 1 to skip writing prompt history and session transcripts to disk. Sessions started with this variable set do not appear in --resume, --continue, or up-arrow history.”
Deleting sessions: claude purge
The sweep deletes old transcripts on its own. To delete a project’s sessions now, the command is claude purge. Its help on 2.1.296:
claude purge --help; echo "exit $?"
Usage: claude purge [options] [path]
Delete all Claude Code state for a project (transcripts, tasks, file history,
config entry)
Options:
--all Purge state for every project (mutually exclusive with
[path])
--dry-run List what would be deleted without deleting anything
-h, --help Display help for command
-i, --interactive Prompt for each item before deleting
-y, --yes Skip confirmation prompt
exit 0
The .claude directory page lists what goes: “Transcripts and auto memory under projects/”, “Per-session tasks/, debug/, and file-history/ entries”, matching lines in history.jsonl, and “The project’s entry in ~/.claude.json”. It also notes “Before v2.1.288, the command was claude project purge.” Without --dry-run, “The command prints the full deletion plan and asks for confirmation before removing anything.” --yes (short -y) skips that question, -i (long --interactive) asks item by item, and --all covers every project.
Here is --dry-run on the scratch project, which has never had a session. Claude Code finds nothing and says so:
claude purge "$PWD/proj" --dry-run; echo "exit $?"
exit 1
On stderr:
No Claude Code project state found for /home/loopdev/dankdev/node_modules/.scratch/resume/proj under /home/loopdev/dankdev/node_modules/.scratch/resume/cfg.
That matches the docs: “If no state matches the path, the command prints an error and exits with status 1.” Next, a placeholder transcript, an empty file named like a session, goes into the directory computed in the naming section:
d="$CLAUDE_CONFIG_DIR/projects/$(printf '%s' "$PWD/proj" | sed 's/[^A-Za-z0-9]/-/g')"
mkdir -p "$d"
touch "$d/11111111-2222-4333-8444-555555555555.jsonl"
ls "$CLAUDE_CONFIG_DIR/projects"
-home-loopdev-dankdev-node-modules--scratch-resume-proj
And the same dry run again:
claude purge "$PWD/proj" --dry-run; echo "exit $?"
Purge plan for /home/loopdev/dankdev/node_modules/.scratch/resume/proj:
dir: /home/loopdev/dankdev/node_modules/.scratch/resume/cfg/projects/-home-loopdev-dankdev-node-modules--scratch-resume-proj
project transcripts (.jsonl) and memory/
Dry run: 1 item(s) would be deleted.
exit 0
On stderr:
backups/ may still contain this project entry in old .claude.json snapshots (/home/loopdev/dankdev/node_modules/.scratch/resume/cfg/backups); at most 5 are kept and they rotate out automatically
The plan names the directory computed earlier, so the naming rule holds on 2.1.296. It lists one item, the transcript directory, and nothing for ~/.claude.json or history.jsonl; the scratch config has no project entry and no prompt history for this path, which is presumably why. The warning about backups/ went to stderr. And the placeholder is still there, because a dry run deletes nothing:
ls "$CLAUDE_CONFIG_DIR"/projects/*/
11111111-2222-4333-8444-555555555555.jsonl
Two things purge does not reach, per the docs: “The command leaves shell-snapshots/ and backups/ alone because those are not project-scoped, and warns about them in the plan output.” and “Images you pasted or attached in the project’s sessions and each session’s scratchpad are stored under Claude Code’s temp directory rather than ~/.claude, so the purge doesn’t remove them.” One more trap: “If you delete a background session with claude rm <id>, its transcript stays on disk and remains available through claude --resume.” Deleting ~/.claude/projects/ by hand costs “Resume, continue, and rewind for past sessions, and auto memory for every project”.
If you got here after quitting a session, How to Stop Claude Code covers the other half: interrupting a turn, quitting, and ending a headless run.
What ran and what did not
Every block above with output under it ran, in the order shown, on Claude Code 2.1.296, inside a network namespace with no network, in one scratch directory with HOME and CLAUDE_CONFIG_DIR pointed inside it and CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC and DISABLE_TELEMETRY set to 1. The scratch directory was deleted afterwards. Each claude command prints its own exit code on its last line. claude purge only ever ran with --dry-run.
Not run: any Claude Code session. That covers claude --continue, claude --resume, /resume, --fork-session and the claude -p example. What they do is quoted from the docs above, not shown.
Follow new posts by RSS: paste dankdev.com/feed.xml into any feed reader. It is a plain XML file — no signup, no email address, no account. Posts land there the same day they go up, and there is nothing to unsubscribe from later.