Skip to main content

Resuming Claude Code Sessions Properly: What Comes Back and What Doesn't

· 12 min read
Pere Pages
Software Engineer
A person at a terminal desk picking up one of several luminous threads that trail from the keyboard back into a dark archive of drawers; the chosen thread glows brighter than the others, and a paper notebook lies open beside the keyboard

I opened Claude Code on a side project after a day away, and it greeted me with a careful reconstruction of what we had been doing, pieced together from the notes file and the working tree. It was right, but it was a guess. The whole conversation that produced that work was sitting on disk, one command away. Here is how sessions actually persist, what a resumed one gives you back, and what it never will.

note

This reflects Claude Code 2.1.x and its documentation as of September 2026. The session picker, the flags and the retention defaults change between releases; check the sessions guide for the current behaviour.

The picture to hold in your head

A Claude Code session is a file on disk, a new session never reads old files, and --resume is how you point a new process at an old file. Everything else follows from those three facts: why a fresh session starts from zero, why the picker only shows some conversations, why sessions vanish after a month, and why a notes file in the repository is still worth keeping even though the transcripts exist.

What happened

The project is a small static site. The previous session had done a batch of search-engine work: sitemap dates from git history, rewritten meta descriptions, longer copy on a thin page, one alt text per photo. None of it was committed. The next morning I started claude in the same directory and asked where we were.

The answer was impressive and slightly unsettling. It listed the uncommitted files, ran the project's check script, summarised the changes from the diff, quoted the next steps from the notes file, and asked whether I had been mid-edit in the one file still open in the editor. Everything was correct. Nothing in it came from the earlier conversation, because the new session had never seen it.

When I asked whether it kept a list of past sessions, it did what I should have done first: listed the transcripts in the project's session folder, four of them, and pointed at the one from the day before.

claude --resume 9c2f0a41-… # yesterday's session, full context, not a summary of it

Then a second question that turns out to have a more interesting answer than I expected: how many sessions does it keep? The last four?

What a session actually is

Every interactive session is written continuously to a transcript file. The format is JSON Lines (JSONL, one JavaScript Object Notation object per line), one entry per message, tool call or piece of metadata. The file lives under your home directory, in a folder named after the project's path with every non-alphanumeric character replaced by a dash:

~/.claude/projects/-Users-pere-Projects-side-project/
├── 9c2f0a41-6d3e-4b8a-9f1c-2e7d5a6b8c01.jsonl
├── 51b7e2d0-8a4c-4f13-b6e9-0c3d7f2a9e44.jsonl
├── d08a3c65-2f1b-4e7d-a5c4-7b9e1f0d2a83.jsonl
└── 2e6f9b17-c4d8-4a02-9e3b-5f1a8c7d0b26.jsonl

That layout explains the first thing people trip over. Sessions are stored per working directory, so the picker in one project never shows the conversations from another. Start claude in a subfolder and you get a different, emptier list. The entry format is internal and changes between versions, so don't build scripts on the raw files; the supported routes for that are /export and claude -p --resume, covered below.

The ways back in

There are five entry points, and they differ in how much you need to remember.

CommandWhat it doesYou need to know
claude --continue (-c)Reopens the most recent conversation in this directoryNothing
claude --resume (-r)Opens the interactive picker for this directoryNothing
claude --resume <name>Reopens a named session directlyThe name
claude --resume <session-id>Reopens one session by id, from any directoryThe id
claude --from-pr <number>Picker filtered to sessions linked to a pull request (PR)The PR number

Inside a running session, /resume opens the same picker and switches conversations without leaving the process. In the picker, Space previews a session, typing filters the list, Ctrl+A widens it to every project on the machine, and Ctrl+B narrows it to the current git branch.

The id-based form is the one nobody remembers, and the fix is to stop needing it. Name your sessions. Start one with claude -n search-pass, or rename the one you are in with /rename search-pass; the name shows in the prompt bar and the picker, and claude --resume search-pass brings it back. Unnamed sessions get an automatically generated title from the first prompt, and that title also works as a resume handle, but "we've published the sitemaps in search google but no results" is not something you will type on purpose.

What comes back, and what doesn't

A resumed session is not a snapshot of the old process. It is a new process reading an old transcript, and the difference shows in what is restored. Launch-time flags are the main casualty: anything you passed on the command line, such as a Model Context Protocol (MCP) server configuration or an extra directory, has to be passed again.

StateOn resumeNotes
Conversation history, tool calls and resultsRestoredA tool that was mid-run when the old process died does not finish or re-run
ModelRestoredUnless a --model flag or environment variable picks one, or the model was retired
Agent (--agent) and its tool restrictionsRestoredLooked up in the session's original directory, then the current one
Permission modeDependsRestored by --continue and --resume <id>; not by the picker or /resume, which use the current default. Bypass mode is never restored
settings.json, CLAUDE.md, rules, skillsRe-readRead fresh at launch, so edits made since apply
--mcp-config, --settings, --plugin-dir, --add-dirNot restoredPass them again on the command line
Directories added mid-session with /add-dirNot restoredThe picker still uses them to find the session
Background Bash commands and monitorsNot restoredScheduled tasks that have not expired are
"Allow for this session" permission grantsNot restoredYou approve again

restored mostly depends not restored

The permission-mode row is the one that bites. Resume through the picker and a session that ended in plan mode starts in whatever mode a new session would; resume the same session with claude --continue and plan mode comes back. Pass --permission-mode explicitly if it matters.

Resuming a long session costs something

Resuming does not make the old conversation free. The prompt cache that kept a long session cheap expires after about an hour of inactivity, so the first request after a resume reprocesses the whole history. On a Pro or Max plan, when the session was idle for more than an hour and is over 100,000 tokens, Claude Code opens a dialog before your first message:

OptionWhat it doesTrade-off
Resume from summaryRuns /compact first: one summarisation request, then the history is replaced by the summary, your latest exchanges and up to five recently read filesCheapest per request afterwards; whatever the summary dropped is gone
Resume full session as-isLoads everything; the first message re-caches the full historyEvery detail available; per-request cost scales with the conversation
Don't ask me againResumes as-is and stops showing the dialogSame as above, permanently
Pick the summary when you are coming back to finish something; pick the full session when you are coming back to argue with a decision, because the reasons live in the parts a summary cuts.

How many sessions are kept

The answer to "the last four?" is that there is no count. Retention is by age: transcripts older than cleanupPeriodDays are deleted, and the default is 30 days. Four was simply how many sessions that directory had seen in the last month; across all projects on the same machine there were 93.

To keep them longer, set the period in your user settings:

~/.claude/settings.json
{
"cleanupPeriodDays": 365
}

Anything already swept is gone; the setting only stops future pruning. To delete a project's transcripts sooner, claude project purge. Transcripts are plain text on disk, so if a conversation contained something you would not want lying around in your home directory, that is the command to know.

Branch instead of overwrite

Resuming writes new messages into the same transcript. That is what you want when you are continuing, and exactly wrong when you want to try a different approach and keep the original intact. Two things help:

  • /branch <name> inside a session copies the conversation so far into a new session and switches you to it. The original stays in the picker unchanged.
  • --fork-session does the same from the command line: claude --continue --fork-session opens the latest conversation under a new id.

One warning the documentation makes and experience confirms: resume the same session in two terminals without forking and both sets of messages interleave into one transcript. If you want two parallel lines of work from the same starting point, fork.

Resume from a script

Sessions are also reachable non-interactively, which is the supported way to get data out of one. Pass the id to print mode and ask a question; the answer comes back as JSON:

claude -p --resume 9c2f0a41-6d3e-4b8a-9f1c-2e7d5a6b8c01 \
--output-format json "summarise what we changed and what is still uncommitted" \
| jq -r '.result'

Sessions created with -p are kept out of the picker and out of --continue, but --resume <id> still finds them. /export is the human-readable counterpart: it writes the current conversation as plain text.

Resume restores conversations; notes restore projects

Now the uncomfortable part of the opening story. The fresh session was right about everything, and it was right because the project keeps a notes file: a CLAUDE.md with a short session log, the decisions made, and the next steps. Claude Code reads that file at the start of every session, resumed or not. The transcript, by contrast, is one directory's private history, expires in a month by default, and is only useful if you remember it exists.

So the two mechanisms are not competing, and the mistake is to lean on either alone.

The habit that makes both work is the last node. Write the session log before you close the terminal, because the transcript remembers what was said and the notes remember what was decided. On the project in the story, the fresh session could reconstruct the pending commit because the previous session had written "nothing is committed yet" into the notes. It could not tell me why one meta-description length had been chosen over another, because that lived in the conversation, and the conversation was a --resume away.

The short version

  • claude --continue when you are picking up yesterday's work in the same directory.
  • claude -n <name> at the start of anything that will take more than one sitting, then claude --resume <name>.
  • --fork-session or /branch before experimenting; never two terminals on one unforked session.
  • Re-pass --mcp-config, --add-dir and friends; everything in settings.json and CLAUDE.md comes back on its own.
  • Raise cleanupPeriodDays if 30 days is shorter than your projects.
  • Keep the notes file current, because it is the only memory that survives the sweep.

References