TLDR; A Claude Code session degrades before you notice: startup overhead claims a slice of your context before you type a word, and quality drops well before auto-compact fires. Manage the lifecycle deliberately:
/clearbetween unrelated tasks,/compactwith explicit preserve instructions,/rewindto recover from a wrong turn, and parallel worktrees when work streams don’t depend on each other. In my own work I’ve since replaced/compactwith a written handoff file and/clear.
The first time Claude Code auto-compacted on me mid-task, I lost twenty minutes of context. I was deep into a client’s API refactor: we’d settled the endpoint naming convention, agreed on the pagination pattern, mapped four controllers. Then the context window filled, auto-compact fired, and Claude forgot the pagination decision entirely. It suggested the exact approach we’d already ruled out.
That session taught me something that took months to act on: a Claude Code session is a finite resource. It has a beginning, a middle where it’s most effective, and an end where quality degrades whether you notice or not. Managing that lifecycle is the skill that separates productive Claude Code use from frustrating.
The session lifecycle
Every Claude Code session starts with overhead before you type a word. The system prompt itself is a few thousand tokens, and your CLAUDE.md files, MCP tool listings, auto-memory, and the compaction buffer stack on top of it; run /context in a fresh session to see your actual breakdown rather than trusting anyone’s published figures, because they drift with every release. On my setup, the working space on a 200,000-token window lands closer to 145,000-167,000 tokens. (Current default models run a 1M-token window natively and auto-compact near 967K; the figures here apply to 200K-window models, and a larger window changes the ceiling, not the discipline, since attention still thins out as you fill it.)
That’s the starting budget. Every file Claude reads, every tool output, every message in both directions eats into it. A typical file read runs 500 to 2,000 tokens. A test suite output can be 5,000+. Ten rounds of conversation with code generation burns through context fast.
The degradation isn’t sudden. The “lost in the middle” paper found position effects on the long-context retrieval and question-answering tasks it studied: information in the middle was often used less reliably than information near the beginning or end. It does not establish a universal Claude Code degradation threshold, but it describes one reason long sessions deserve active verification.
Auto-compaction reserves part of the context window and its effective trigger can change by model and release. On my setup, waiting for the default trigger has often been too late for a clean handoff. I start checking the session more deliberately when roughly 50,000 tokens remain.
Three working phases from my own tracking, not product guarantees:
- Fresh (0–40% utilisation): Claude follows all instructions, remembers everything
- Working (40–65% utilisation): still effective, but start thinking about whether to compact or clear
- Degrading (65%+): missed instructions, repeated suggestions, contradicting earlier decisions. Intervene now or pay in rework
When to start fresh
The /clear command is the most underused tool in Claude Code. The command itself does not invoke another model turn; it wipes conversation history and gives you a clean context window. Re-establishing the task afterward still consumes tokens.
I use /clear between every unrelated task. Finish a feature, commit it, /clear, start the bug fix. The context from the feature build doesn’t help with the bug, and carrying it forward has a real cost: it fills the window faster and increases the chance of Claude confusing instructions from one task with another.
The re-establishment cost, Claude reloading your CLAUDE.md, reading a few key files to orient itself, runs to roughly 3,000–5,000 tokens. Trivial compared to fighting a degraded 150,000-token session where Claude has lost track of what you’re doing.
My rule: if the next task doesn’t need the context from the current one, clear. This applies more often than you’d think:
- Switching between client projects
- Moving from backend to frontend work on the same project
- After a long debugging session (the failed attempts are noise)
- After committing a feature (the implementation details are in git now)
- When Claude starts repeating itself or missing instructions you’ve already given
That last one is the tell that catches people off guard. When Claude suggests something you explicitly ruled out two exchanges ago, the session has degraded. Don’t course-correct. Clear and restart. Three minutes of re-establishment beats twenty minutes of fighting.
Boris Cherny, who created Claude Code, treats sessions as disposable by default. His workflow runs about five local sessions, each in its own git checkout, plus more on the web. Each session focuses on a single task with a lean context window. The official best practices reflect the same idea: short, focused sessions beat sprawling marathons.
When to resume
Not every session should be thrown away. The --continue flag picks up your most recent session; --resume lets you choose from a list of past sessions. Both restore the full conversation history.
Resume when you’ve invested significant context-building that would be expensive to reproduce. If you spent fifteen minutes helping Claude understand a complex model hierarchy, the relationships between six Active Record models, the polymorphic associations, the edge cases in validation logic, that understanding has real token value. Starting fresh means rebuilding it.
My naming convention makes sessions findable:
feature-invitation-system: feature workbugfix-mailer-encoding: debugging sessionsexplore-auth-middleware: research and orientation
The resume decision comes down to freshness. I’ll resume a session from earlier today without hesitation. A session from yesterday, maybe, if the files haven’t changed. Three days ago, almost never. Code changes between sessions create a gap between what Claude remembers and what’s on disk, and that gap produces subtle bugs.
There’s also a middle option worth knowing: forking. In a running session, /branch copies the transcript, switches you into the copy, and leaves the original untouched; from the CLI, claude --continue --fork-session does the same for your most recent session. I use this when I want to try a different approach without losing the original session; fork to explore option B while option A stays intact as a fallback. One difference between the two: /branch stays in the same process, so “allow for this session” permission grants carry over, while --fork-session starts fresh and re-approves from scratch.
One anti-pattern to avoid: resuming a degraded session. If you compacted and then stopped working, resuming gives you the compacted context, which might be missing details you need. Better to start fresh and re-read the relevant files than to build on a lossy foundation.
Compact with intent
The /compact command summarises conversation history to free context. The before-and-after token counts vary by model, context window, configuration, and release. It is lossy by design, and what survives depends partly on what you tell it to preserve.
Compaction without guidance is a blunt instrument. Claude decides what’s important based on recency and frequency. The architectural decision you made forty minutes ago, the one that shapes everything else, might get compressed to a single line or dropped entirely.
Guided compaction changes this:
/compact Preserve: the API endpoint naming convention (kebab-case,
versioned under /api/v1/), the pagination approach (cursor-based,
not offset), and the three test failures we haven't addressed yet.
Now Claude knows what to keep. The implementation details of the six files you’ve already committed can be safely compressed. The open decisions stay intact.
When to compact
Don’t wait for auto-compact. When I compacted, my working threshold was roughly 50,000 free tokens remaining, around 60–65% utilisation on a 200K-window model. That is a personal operating threshold, not a documented quality boundary.
To trigger auto-compact earlier, there’s an environment variable:
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=65
This fires compaction at 65% of the auto-compact window. Per Anthropic’s docs the override applies to any session that compacts before the model’s context limit, which includes default 1M-token sessions that auto-compact near 967K. In my testing, 65–70% works well when it does apply: early enough that the session is still sharp when compaction runs, and the summary is more accurate as a result. Confirm it’s actually firing at your threshold before relying on it.
Verify after compaction
Always check that Claude retained what matters. Ask a specific question about a decision you need it to remember: “What pagination approach did we agree on?” If it can’t answer correctly, the compaction lost something and you’re better off starting fresh with a clear brief.
If a compaction (or any single bad turn) drops something you needed, /rewind restores the session to an earlier checkpoint rather than making you reconstruct it by hand. It’s the counterpart to /clear: /clear throws context away deliberately, /rewind recovers context you didn’t mean to lose. Checkpoints are cheap; reach for it before you resign yourself to a fresh start.
What I do now: a handoff, then /clear
I’ve moved on from /compact. At a task boundary, or around 50 turns, I run a /handoff skill I wrote. The session writes a short markdown file to .claude/handoffs/: the decisions and why they were made, what was tried and failed, where things stand, and the one next action. Then I run /clear. A SessionStart hook loads the newest handoff for the current branch into the fresh session. The skill and its hooks now ship in hamster, my open-source plugin, which also turns repeated mistakes into hook rules.
The reason is inspection. A compaction summary is written by the model for the model, and it never shows in my terminal. A handoff is a file I can read and correct before the next session acts on it. It also survives a crashed terminal.
The habit stuck. Over five weeks my manual compactions fell from 35–40 a week to none in the last three, and no session ran past 50 turns. /compact is still the right tool when you want to keep going in the same thread; I just rarely want to.
The file-based alternative
There’s a pattern that sidesteps the compaction problem entirely: write plans and decisions to files on disk, not to the conversation.
When I’m working on a complex feature, I ask Claude to write the implementation plan to a markdown file early in the session. As we make decisions, I have Claude update the file. When compaction fires, or when I start a fresh session the next day, the plan file is still there, uncompressed, with every detail intact. Claude re-reads it and picks up exactly where we left off.
Practitioners refine it further by annotating plan files inline across multiple rounds rather than discussing changes in chat.
I take this further with a /tech-lead orchestration skill, but the reason has shifted recently. Claude Code’s built-in TaskCreate / TaskList / TaskUpdate tools now persist to ~/.claude/tasks/ with their own state machine, dependencies, and TaskCreated / TaskCompleted hooks, so surviving /clear is no longer the problem the file-based pattern solves. The argument now is coupling: task state belongs in the repo, alongside the spec it satisfies and the code that closes it out.
Approved PRDs live at docs/prd/YYYY-MM-feature-name.md, and a sibling .tasks.md file holds the broken-down tasks with stable T-N IDs, statuses, dependencies, and the branch name for each. Native task state in ~/.claude/tasks/ is the runtime; .tasks.md is its in-repo mirror. Every state change is dual-written, TaskUpdate in memory and an Edit to the .tasks.md file, and both are committed together in the feature commit, so each commit is a complete unit of code plus state. A git revert rolls them back in one move, and a teammate can read the file in a PR review without running Claude at all.
After /clear or a fresh session the next day, the tech-lead skill’s resume step (not the built-in /resume, which opens the session picker) globs docs/prd/*.tasks.md, parses the ## T-N: headings, replays TaskCreate in T-N order so runtime IDs align with file IDs, and restores statuses and dependencies. The session is back where it was in seconds, with no inferred context.
The piece that makes this work is the stable ID. T-3 means the same task in the file, in the in-memory task list, and in the branch name (feature/T-3-sessions-controller). Plan files give you the what across compactions; stable IDs and in-repo state give you the which across sessions and reviewers.
Conversations compress. Files don’t.
Rewind when things go sideways
The third intra-session lever, alongside /clear and /compact, is /rewind, bound to a double-tap of Esc, or typed directly. It opens a list of every prompt in the session. Pick a point, then choose what to restore.
Five options, plus a cancel:
- Restore code only: revert file changes, keep the conversation
- Restore conversation only: keep the files, rewind Claude’s memory
- Restore both: full reset to that point
- Summarize from here: collapse messages from the chosen point forward into an AI-generated summary, leaving earlier context untouched
- Summarize up to here: the mirror image, compress everything before the chosen point and keep the recent messages intact
Those last two are targeted compaction. Where /compact summarises everything, “Summarize from here” preserves the early architectural setup in full fidelity and only compresses the verbose debugging that came after; “Summarize up to here” does the opposite, squeezing a long-settled preamble while the current working thread stays sharp. Either is more accurate than a full compact when you know which part of the conversation is the bloat.
The three restore modes map to three failure shapes:
- Code only: Claude understood the task but the implementation broke. The conversation is still useful, the problem analysis, the alternatives considered, the half-formed plan, but the files are wrong. Roll the files back, keep talking.
- Conversation only: the files work but Claude’s mental model has drifted. It’s referencing methods that don’t exist, contradicting decisions you’d made, suggesting things you ruled out. Wipe the conversation back to the last sane prompt; the working code stays.
- Both: the experiment didn’t pan out and you want to start the branch over from a known-good point.
The “code only” mode is the one that earns its keep. A multi-file refactor that compiles in pieces but breaks in aggregate, an over-eager rename that touched the wrong file, a test-driven change that overshot, restore the files, leave the conversation intact, and Claude already knows what to try differently.
The bash gotcha
/rewind only tracks edits made through Claude’s file-editing tools. Anything Claude does via bash, rm, mv, cp, sed in place, a migration that drops a column, a script that rewrites a config, is permanent. Before letting Claude run a destructive shell command, commit. The checkpoint system won’t save you.
External edits aren’t tracked either. If you opened a file in your editor and saved a change between Claude’s prompts, that change won’t appear in the rewind history. Two more blind spots worth knowing: edits made by subagents aren’t restored by /rewind (only a foreground forked skill’s edits are), and symlinked or hard-linked files are skipped on restore with a warning.
Where it fits with /clear and /compact
The three commands solve different problems:
/compactis preventative, run before quality degrades/clearis for context that’s no longer relevant/rewindis for recovery, Claude went somewhere wrong and you want a specific point back
The most useful combination is /rewind followed by a sharper prompt. You’re not asking Claude to course-correct from a degraded position; you’re rolling back to clean state and trying again, with what you learned from the failed attempt informing the next prompt.
Checkpoints persist for 30 days by default and survive across resumed sessions, so a session restarted the next morning can still rewind into yesterday’s work. They are not a replacement for Git. Think of them as session-scoped undo, with Git handling permanent history, checkpoints for mid-task experiments, commits for milestones you want to keep.
The checkpoint rhythm
The session lifecycle maps naturally to a commit rhythm:
- Explore: let Claude read the relevant files and understand the current state
- Plan: enter Plan Mode (Shift+Tab) for anything non-trivial, iterate until the approach is solid
- Code: exit Plan Mode, implement. Well-planned tasks often complete in a single pass
- Commit: checkpoint the work before moving to the next task
Committing here is a session-management decision as much as version-control hygiene. A commit creates a clean rollback point. If the next task goes sideways, inspect the diff and restore the intended tracked files from that checkpoint. git checkout . only restores tracked paths and leaves untracked files behind, so it is not a complete or reviewable rollback procedure.
This matters most for autonomous work. When you give Claude a complex task and let it run for several minutes, there’s a real risk of it going off course. The r/ClaudeCode community has converged on a clear consensus: when Claude makes a mistake deep in a long session, the context is already cluttered with the failed attempt. Trying to fix within that degraded context usually produces more mistakes. Roll back to the checkpoint, start a fresh session with a refined prompt, and the second attempt is almost always cleaner.
My rhythm:
- Commit clean state
- Give Claude the task
- Review the result
- Good? Commit and continue
- Bad?
/rewindto the clean state and try again with a better prompt. If Claude changed files through bash, inspectgit statusand restore the explicit tracked paths from your checkpoint; handle any untracked files separately rather than assuminggit checkout .removed them
One thing Plan Mode buys that’s easy to miss: a well-planned task uses less context than an unplanned one. The five minutes in Plan Mode often saves twenty minutes of course corrections that would have filled the window. Pour energy into the plan so Claude can one-shot the implementation.
Parallel sessions
The structural alternative to managing one long session is not managing it at all: run multiple short sessions in parallel.
Claude Code’s --worktree flag (or -w shorthand) creates an isolated git worktree for each session. Each worktree is a separate checkout of your repository on its own branch. The sessions can’t see each other, can’t step on each other’s files, and each maintains its own clean context window.
# Terminal 1
claude -w feature-invitation-model
# Terminal 2
claude -w feature-invitation-tests
# Terminal 3
claude -w feature-invitation-docs
Three sessions, three branches, three independent context windows. While one session is processing a ten-minute autonomous task, you’re working in another. When they’re done, merge the branches in dependency order.
The incident.io engineering team went from no Claude Code to four or five Claude agents running in parallel within four months of adopting this pattern. They built a custom worktree manager so team members could spin up isolated sessions with a single command. A fan-made collection of Boris Cherny’s posts calls parallel worktree sessions his biggest productivity gain, and the top tip from the entire Claude Code team.
I typically run 2–3 worktree sessions during a feature build. More than that and the cognitive overhead of tracking what each session is doing outweighs the parallelism benefit, at least for my workflow. The right number depends on how independent the work streams are and how much context-switching you can handle.
The worktree pattern pairs naturally with the checkpoint rhythm: each worktree session follows its own explore-plan-code-commit cycle. When all sessions are done, merge the branches, resolve any conflicts (usually in routes or configuration files), and run the full test suite on the merged result.
Worktrees are the manual end of the parallel spectrum, and they’re where I’d start. The heavier-weight alternative is agent teams, an experimental Claude Code feature where multiple sessions coordinate through shared tasks and messaging under a team lead. Each active teammate carries its own context and model usage, so total consumption scales with team size and duration rather than a fixed multiplier. It earns its keep only when the work benefits from that coordination.
For the full parallel execution model, including cost modelling, agent briefing patterns, and a real case study with token breakdowns, see the multi-agent orchestration guide.
Review sessions
The meta-practice that makes everything else better: use Claude to audit how the previous session went.
Mine is a /review-session command I run at the end of significant work sessions. It reads the conversation history and reports where I was effective, where I wasted context, and where my prompting could improve:
- repeatedly re-explaining a constraint that should have been in CLAUDE.md
- running exploration in the main session when a subagent would have been cleaner
- compacting without preservation instructions Each finding comes with an offer to fix the cause, a CLAUDE.md line, a new skill, a hook, so the lesson lands somewhere permanent instead of evaporating with the session. Findings that generalise beyond one project go into a knowledge vault, a plain directory of markdown entries that any future session can search.
The rule I used most came out of exactly this loop and sat in my global CLAUDE.md for months: /compact if the next task is related, /clear if it isn’t. The same loop later replaced it. My global CLAUDE.md now says /handoff then /clear, never /compact, because a handoff file carries the related context forward without the lossy summary.
Over three months of periodic session reviews, my average session efficiency has improved noticeably. Sessions run longer before degrading because less context is wasted on avoidable repetition. The work per session has increased while the cost per session has stayed flat.
When a whole team uses Claude Code and habits differ by person, agreeing one routine is an early job when I join as a fractional CTO.
Related reading
- Skills, hooks, agents, and commands, the definitive guide, the extensibility primitives that make session management automatic
- Multi-agent orchestration, running parallel agents on real projects, the full parallel execution model with cost data
- Token economics, what Claude Code actually costs, understanding the cost model behind context management
- Claude Code hook examples: turning mistakes into tested rules, the open-source plugin that ships the handoff skill
- Top 10 ways to optimise Claude Code token usage, practical techniques for session efficiency
Sources
- Lost in the Middle: How Language Models Use Long Contexts, Liu et al., 2023. The research behind context window degradation patterns. Academic paper
- Best Practices, Claude Code Docs, Official Anthropic guidance on session management and workflow. Documentation
- Checkpointing, Claude Code Docs, Official documentation on
/rewind, restore modes, and the limitations around bash-modified files. Documentation - How Boris Uses Claude Code, Boris Cherny’s parallel session workflow and productivity patterns. Secondary source (fan-made collection)
- How we’re shipping faster with Claude Code and Git Worktrees, incident.io engineering team on scaling parallel worktree adoption. Case study
Common questions
When should you start a fresh Claude Code session?
When the task changes or the context is full of work that no longer helps. A session has a productive middle and a tail where quality quietly degrades; starting fresh on a new task keeps the context relevant rather than cluttered.
When should you compact a session instead of starting over?
Compact when the thread is still relevant but long: it preserves the useful state while clearing the noise. Start fresh when the next task is unrelated. I’ve since stopped compacting: at a task boundary I have the session write a handoff file with the decisions, what failed and the next action, then run /clear and load the file into the new session.
How do you stop session quality from degrading?
Manage the lifecycle deliberately: checkpoint at a rhythm, compact with intent, and rewind when things go sideways rather than fighting a confused thread. Treating the session as a finite resource is what keeps the tail from eroding quality.