How sessions are stored
Each session is identified by a UUID and persisted on disk as a newline-delimited JSON log (.jsonl) in ~/.claude/projects/<project-slug>/. The log file grows append-only: new entries are streamed to disk as they are produced, so the history survives unexpected exits.
The storage layer is implemented in utils/sessionStorage.ts. The session ID is assigned at startup and carried in global state (bootstrap/state.ts). Related metadata — the working directory, the active permission mode, any agent-subagent relationships — is saved alongside each entry.
Session persistence can be disabled with the
--no-session-persistence flag (only valid with --print mode). In that mode nothing is written to disk and the session cannot be resumed later.Resuming a session
Pass--resume (or -r) to pick up where a previous session ended:
Locate the log file
The session log for the requested ID is read from
~/.claude/projects/<project-slug>/.Replay message history
All persisted messages are loaded and replayed into the conversation context so Claude can see the full prior exchange.
Restore working state
The working directory, permission mode, and any active agent definitions are restored to match the state at the end of the last session.
Listing past sessions
Use the/session command inside a Claude Code session to browse sessions, or use the --resume flag with no argument to open the interactive session picker:
listSessions() to list sessions programmatically — see the SDK Sessions reference.
Compact — summarizing the conversation
As a session grows, it eventually approaches the model’s context-window limit. The/compact command (implemented in commands/compact/compact.ts) replaces the full message history with a dense summary produced by a secondary model call, freeing context for further work.
What happens during compaction
Pre-compact hooks run
Any configured
PreCompact hooks execute first (see the hooks documentation). Hooks can inject additional instructions that are merged with any custom instructions you provided.Microcompact pre-processing
A lightweight pass removes redundant tool results and verbose output from the message list to reduce the payload sent to the summarization model.
Summarization model call
The full message list is sent to a secondary Claude model with instructions to produce a compact but complete summary of everything that happened.
Context is replaced
The conversation history is replaced by the summary. A
SystemCompactBoundary marker is written so the UI can still show where compaction occurred.Compaction result
After a successful/compact, the original full transcript is still available for scrollback in the UI (ctrl+o to expand). Only the live context sent to the model is replaced.
Session metadata
Each log entry carries a rich set of metadata fields including:| Field | Description |
|---|---|
sessionId | UUID identifying the session |
agentId | UUID identifying the specific agent within the session (main thread or subagent) |
cwd | Working directory at the time the entry was written |
timestamp | Unix timestamp in milliseconds |
type | Entry type: user, assistant, system, tool_result, etc. |