7 KiB
| title | aliases | tags | sources | created | updated | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sessions — Persisting and Resuming Conversation History |
|
|
|
2026-04-17 | 2026-04-17 |
Sessions — Persisting and Resuming Conversation History
A session is the full conversation history the SDK accumulates during a query() run: your prompt, every tool call, every tool result, every response. The SDK writes it to disk automatically under ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl.
Sessions persist the conversation, not the filesystem. To snapshot/revert file changes use wiki/agent-sdk/file-checkpointing.
Choosing an Approach
| Scenario | What to use |
|---|---|
| One-shot task, no follow-up | Nothing extra. One query() call. |
| Multi-turn chat in one process | ClaudeSDKClient (Python) or continue: true (TypeScript) |
| Pick up after a process restart | continue_conversation=True / continue: true — resumes most recent session, no ID needed |
| Resume a specific past session | Capture session ID → pass to resume |
| Try an alternative without losing original | Fork the session |
| Stateless, no disk writes (TypeScript only) | persistSession: false |
Automatic Session Management
Python — ClaudeSDKClient
ClaudeSDKClient tracks the session ID internally. Every client.query() call automatically continues the same session. Use it as an async context manager.
async with ClaudeSDKClient(options=options) as client:
await client.query("Analyze the auth module")
async for message in client.receive_response():
print_response(message)
# automatically continues same session
await client.query("Now refactor it to use JWT")
async for message in client.receive_response():
print_response(message)
TypeScript — continue: true
The stable V1 query() has no session-holding client object. Pass continue: true on each subsequent call — SDK finds and resumes the most recent session on disk.
// First query — creates a new session
for await (const message of query({ prompt: "Analyze the auth module", ... })) { ... }
// Second query — resumes most recent session
for await (const message of query({
prompt: "Now refactor it to use JWT",
options: { continue: true, allowedTools: [...] }
})) { ... }
V2 preview (
createSession()/send/stream) is closer to Python's client feel but is unstable — stick to V1 for production. See wiki/agent-sdk/typescript-v2-interface.
Manual Session Options with query()
Capture the Session ID
Read session_id from the ResultMessage — present on every result, success or error.
async for message in query(prompt="...", options=ClaudeAgentOptions(...)):
if isinstance(message, ResultMessage):
session_id = message.session_id
In TypeScript the ID is also on the init SystemMessage (earlier than ResultMessage).
Resume by ID
async for message in query(
prompt="Now implement the refactoring you suggested",
options=ClaudeAgentOptions(
resume=session_id,
allowed_tools=["Read", "Edit", "Write", "Glob", "Grep"],
),
): ...
Common resume use cases:
- Follow up on a completed task without re-reading files
- Recover from
error_max_turnsorerror_max_budget_usdwith higher limits - Restore a conversation after process restart
Gotcha — mismatched cwd: Sessions are stored under ~/.claude/projects/<encoded-cwd>/. If the resume call runs from a different directory, the SDK looks in the wrong folder and returns a fresh session. The cwd must match exactly.
Fork to Explore Alternatives
Fork creates a new session starting with a copy of the original's history. The original stays unchanged. Both sessions get their own IDs and can be resumed independently.
# Fork: branch from session_id, try OAuth2
forked_id = None
async for message in query(
prompt="Instead of JWT, implement OAuth2 for the auth module",
options=ClaudeAgentOptions(resume=session_id, fork_session=True),
):
if isinstance(message, ResultMessage):
forked_id = message.session_id
# Original session untouched — continue JWT thread
async for message in query(
prompt="Continue with the JWT approach",
options=ClaudeAgentOptions(resume=session_id),
): ...
Fork branches conversation history only. File changes from a forked agent are real and visible to all sessions in the directory. To branch files too, combine with wiki/agent-sdk/file-checkpointing.
Resume Across Hosts
Session files are local to the machine that created them.
| Option | How |
|---|---|
| Move the file | Persist ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl, restore it to the same path on the new host, ensure cwd matches |
| Skip session resume | Capture the output you need (analysis, decisions, diffs) and pass it into a fresh session's prompt — often more robust |
Session Utility Functions
Both SDKs expose helpers for working with sessions on disk:
| Purpose | Python | TypeScript |
|---|---|---|
| List sessions | list_sessions() |
listSessions() |
| Read messages | get_session_messages() |
getSessionMessages() |
| Get session info | get_session_info() |
getSessionInfo() |
| Rename session | rename_session() |
renameSession() |
| Tag session | tag_session() |
tagSession() |
Use these to build custom session pickers, cleanup logic, or transcript viewers.
Key Takeaways
- Sessions = serialized conversation history (prompts + tool calls + results), written as
.jsonlfiles - Continue = resume most recent session by directory; no ID needed
- Resume = return to a specific session by ID; required for multi-user or non-latest sessions
- Fork = copy history into a new session; original untouched; both independently resumable
- Mismatched
cwdis the #1 cause of resume returning a blank session - For cross-host resuming, moving the
.jsonlfile is possible but passing output as a fresh prompt is more robust persistSession: false(TypeScript only) keeps the session in memory only — nothing written to disk
Related
- wiki/agent-sdk/agent-loop — how turns, messages, and context accumulate within a session
- wiki/agent-sdk/file-checkpointing — track and revert file changes across sessions
- wiki/agent-sdk/python-api-reference —
ClaudeAgentOptionssession fields reference - wiki/agent-sdk/typescript-api-reference —
Optionssession fields reference - wiki/agent-sdk/typescript-v2-interface — V2
createSession()/resumeSession()preview - wiki/agent-sdk/streaming-input — notes on session resuming with streaming input
Sources
raw/Work with sessions.md— official Agent SDK sessions documentation