Your multi-step pipeline works in sequence but takes 20 minutes. You try to parallelize by forking the session — and discover that forked sessions share the initial context but not subsequent updates from sibling forks. Advanced session patterns require understanding what state transfers and what doesn’t.
This chapter covers advanced session patterns. For session basics (create, resume, continue), see Working with Sessions.
Branching with —fork-session
The --fork-session flag creates a new session with a copy of the conversation history. The original session is left untouched:
claude -p "Try approach B instead" \ --resume "$SESSION" --fork-session --output-format jsonThis gives you a clean branch point. The forked session has its own UUID and its own future, while the original remains available for --resume. Use cases include:
- A/B testing approaches — fork at the same decision point and compare results
- Exploring alternatives — try a risky refactor without losing the main thread
- Chain forks — fork a fork to create tree-shaped exploration (each fork gets a fresh UUID)
Here is a real fork response showing the new session ID:
The original session (4b8101c6-...) still returns “BASE_MESSAGE” when resumed — forking is completely non-destructive.
Fork a session and test context isolation:
SID=$(claude -p “Remember: the code is 42” —output-format json | jq -r ‘.session_id’)
claude -p “What is the code?” —resume “$SID” —output-format json | jq ‘.result’
claude -p “Change the code to 99. What is the code now?” —resume “$SID” —output-format json | jq ‘.result’
Does the second resume see the change from the first resume, or does each fork get the original state?
Concurrent Sessions
Multiple claude -p calls can run in parallel in the same directory without conflicts. Each gets a unique session ID and independent context:
# Both run simultaneously, no lockingclaude -p "Review auth module" --output-format json > review_auth.json &claude -p "Review database module" --output-format json > review_db.json &waitThere is no session locking mechanism. Parallel calls do not interfere with each other.
Which Session Does —continue Pick?
When multiple sessions exist in a directory, --continue picks the most recently created one. It does not pick the most recently modified or the one that ran longest.
--continue Resolution Rules
| Scenario | Result |
|---|---|
| One session in directory | Picks that session |
| Multiple sessions in directory | Picks the most recently created |
| Sessions in parent and subfolder | Only sees sessions from current directory |
| No sessions in current directory | Error: no session to continue |
Sessions are stored in ~/.claude/projects/<encoded-dir-path>/, which is why --continue is directory-scoped. Use --resume SESSION_ID when you need to target a specific session regardless of directory.
For parallel workflows where you need to continue specific sessions later, capture the session_id from each JSON response and use —resume instead of —continue. This eliminates ambiguity about which session gets continued.
Deterministic Session IDs
The --session-id flag assigns a specific UUID to a new session, enabling deterministic naming for CI correlation:
# Assign a deterministic session ID for CI traceabilityclaude -p "Run linting" \ --session-id "$(uuidgen)" \ --output-format jsonKey behaviors confirmed experimentally:
- The returned
session_idis exactly the UUID you provide — no prefix or suffix added - The value must be a valid UUID (8-4-4-4-12 hex format). Non-conforming strings silently produce empty output
- Reusing an already-active session ID produces:
Error: Session ID <uuid> is already in use --session-idis for assignment only — it does NOT resume. Use--resumefor that- Combining
--resumewith--session-idrequires--fork-session(fork-to-new-ID semantics)
# Fork a session to a new deterministic IDclaude -p "Continue with approach B" \ --resume "$OLD_SESSION" \ --session-id "$NEW_UUID" \ --fork-sessionWhile concurrent claude -p sessions are safe in practice (each gets a unique session ID and independent context), community reports indicate that interactive sessions can corrupt .claude.json state files when multiple instances modify them simultaneously. This is because .claude.json uses no file locking. For headless (-p) mode, sessions are stored in ~/.claude/projects/ with per-session isolation and are not affected. For interactive sessions, avoid running multiple instances in the same project directory.
See how —resume + —fork-session powers a real discussion system with three branching strategies in Build an MR Reviewer, Part 4: Fork Sessions for Discussions.
Fork a session: capture a session ID, then resume it twice with different prompts. Verify that each fork gets the original context but doesn’t see the other fork’s changes. This is the pattern for parallel task execution — branch from a common plan, execute independently.