Claude Code Project Checkpoints: Saving and Restoring Agent State Across Long Autonomous Sessions
Most autonomous agent failures stem from state corruption during long sessions. Learn how Claude Code's checkpoint system enables reliable rollback and recovery patterns for multi-hour coding sessions.
Most autonomous agent problems stem from state drift during long sessions. The agent makes ten good decisions, then one catastrophic edit. Without checkpoints, engineers face a choice: manually undo the damage or abandon hours of work. Neither option is acceptable in production.
Claude Code solves this with automatic checkpoints before every file change. The agent writes a function, snapshots the state. Refactors a class, snapshots again. Developers can rewind to any point in the session, restoring code, conversation, or both. The failure mode disappears.
flowchart LR
Start("Agent begins session") --> Edit1("Makes 10 good edits")
Edit1 --> Bad("Catastrophic edit corrupts state")
Bad --> Manual("Manual cleanup or abandon session")
Manual --> Hours("Hours of work lost")
style Bad stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
style Hours stroke:#ef4444,fill:#450a0a,color:#fca5a5
The checkpoint system creates a safety net. Engineers let agents run longer, tackle bigger refactors, and recover instantly when things break. The cost is zero—checkpoints happen automatically, stored in memory, no manual intervention.
flowchart LR
Start("Agent begins session") --> Edit1("Makes 10 good edits")
Edit1 --> Bad("Catastrophic edit detected")
Bad --> Rewind("/rewind to previous checkpoint")
Rewind --> Restore("State restored in 2 seconds")
Restore --> Continue("Continue from safe point")
style Rewind stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style Restore stroke:#34d399,fill:#0b3b2e,color:#d1fae5
style Continue stroke:#34d399,fill:#0b3b2e,color:#d1fae5
This distinction is critical. Checkpoints turn autonomous agents from fragile experiments into reliable tools. Teams that master checkpoint patterns ship features faster because they trust the agent to explore without breaking production code.
Key Takeaways
- Claude Code automatically checkpoints before every file change, creating a complete history of code and conversation state.
- The
/rewindcommand restores previous states in seconds, eliminating manual cleanup after agent mistakes. - Checkpoint strategies determine how long agents can run autonomously—proper patterns enable multi-hour sessions without risk.
- Selective restore lets developers keep good changes while rolling back only the broken parts.
- Production teams integrate checkpoints with Git stash to create layered recovery options for complex refactors.
How Claude Code Checkpoints Work: Automatic Snapshots Before Every Change
Claude Code checkpoints capture the complete agent state before each modification—file contents, conversation history, pending edits. The system stores these snapshots in memory, building a timeline engineers can navigate with /rewind. No configuration required. The agent handles it automatically.
The checkpoint mechanism triggers on every file write operation. When the agent modifies auth.ts, the system snapshots the file's current state, the conversation leading to that change, and any uncommitted edits in the workspace. The agent then proceeds with the modification. If the change breaks something, developers rewind to the pre-modification state.
The implication here is that checkpoint granularity matches the natural unit of work—one function, one class, one configuration change. Engineers don't checkpoint arbitrary line counts. They checkpoint semantic changes. This matters because recovery becomes surgical. Rewind to before the authentication refactor. Keep everything after it.
flowchart TD
Session("Active coding session") --> Request("Agent receives task")
Request --> Checkpoint("Automatic checkpoint created")
Checkpoint --> Analysis("Agent analyzes codebase")
Analysis --> Edit("File modification planned")
Edit --> PreWrite("Pre-write snapshot captured")
PreWrite --> Write("Changes written to disk")
Write --> Verify("Verification step")
Verify --> NextTask("Ready for next task")
NextTask --> Request
style PreWrite stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style Write stroke:#34d399,fill:#0b3b2e,color:#d1fae5
Checkpoints persist for the session duration. When engineers close Claude Code, the checkpoint history clears. This design prevents checkpoint bloat—multi-day sessions don't accumulate gigabytes of snapshots. The tradeoff is intentional: checkpoints serve immediate recovery, not long-term audit trails. Git handles that.
The system stores up to 50 checkpoints by default. Older checkpoints expire as new ones arrive. For typical refactoring sessions, 50 snapshots covers 2-3 hours of continuous agent work. Engineers working on larger transformations can adjust this limit, but most production scenarios stay well under the threshold.
Context preservation is what separates checkpoints from simple undo. Traditional undo restores file state but loses the reasoning. Checkpoints restore both. The agent's explanation for adding that validation layer? Preserved. The conversation about error handling strategy? Intact. Engineers rewind and immediately understand why the agent made those choices.
Using /rewind to Restore Previous States: Code, Conversation, or Both
The /rewind command opens an interactive timeline showing every checkpoint in the current session. Engineers navigate with arrow keys, previewing changes at each point. Press Enter to restore. The agent reverts to that exact state—code, conversation, pending edits—in under two seconds.
flowchart LR
Problem("Agent breaks authentication") --> Esc("Press Esc twice or /rewind")
Esc --> Timeline("Interactive checkpoint timeline appears")
Timeline --> Navigate("Arrow keys to preview states")
Navigate --> Select("Enter to restore chosen point")
Select --> Restored("Code and conversation restored")
Restored --> Continue("Continue from safe state")
style Timeline stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style Restored stroke:#34d399,fill:#0b3b2e,color:#d1fae5
style Continue stroke:#34d399,fill:#0b3b2e,color:#d1fae5
The timeline displays three pieces of information for each checkpoint: timestamp, affected files, and a one-line summary. Engineers see "14:32 - Modified auth.ts, user.ts - Added session validation" and immediately know if that's the restore point they need. The interface shows diffs on demand. Preview the changes before committing to a restore.
Selective restore gives engineers control over what reverts. Restore code but keep conversation. Restore conversation but keep code changes. Restore specific files while leaving others untouched. This granularity matters when the agent made five good changes and one bad one. Engineers keep the good work and undo only the failure.
The practical pattern looks like this in a multi-step refactor:
// Session state before checkpoint
interface User {
id: string;
email: string;
role: string;
}
// Agent adds permissions system (Checkpoint A)
interface User {
id: string;
email: string;
role: string;
permissions: Permission[];
}
// Agent refactors auth logic (Checkpoint B)
class AuthService {
validatePermissions(user: User, required: Permission[]): boolean {
return required.every(p => user.permissions.includes(p));
}
}
// Agent breaks session handling (Checkpoint C - PROBLEM)
class SessionManager {
// Incorrect implementation that loses user context
createSession(user: User): Session {
return { userId: user.id }; // Missing permissions!
}
}
// Developer rewinds to Checkpoint B
// Keeps permissions system and auth refactor
// Loses broken session handling
// Continues from safe stateThe recovery time is what makes this practical. Traditional approaches require identifying the bad commit, checking out the previous version, manually reapplying subsequent good changes, and testing everything. That's 15-30 minutes minimum. Checkpoints reduce it to literal seconds. Preview, select, restore. Back to productive work.
Keyboard shortcuts accelerate the workflow. Esc stops the agent mid-action, preserving context. Esc + Esc or /rewind opens the timeline immediately. Engineers don't type commands during emergencies. Two keystrokes and the recovery interface appears.
The failure mode here is subtle but expensive: developers who don't know about checkpoints let broken sessions run too long. The agent makes 30 edits, 5 are wrong, now untangling them manually takes an hour. Checkpoint-aware engineers stop at edit 1, rewind, redirect. The session stays productive.
Building Checkpoint Strategies for Multi-Hour Autonomous Sessions
Long autonomous sessions require explicit checkpoint strategies because implicit checkpoints alone don't provide enough control. Engineers working on complex refactors create manual checkpoints at logical boundaries—before major architectural changes, after successful test passes, at the completion of each module.
The pattern starts with a planning checkpoint. Before the agent begins a large refactor, create a named checkpoint: "Pre-migration baseline". This establishes a known-good state to return to if the entire approach fails. The agent can then explore aggressively, knowing the baseline remains intact.
// Checkpoint strategy for a database migration
// Manual checkpoints at each critical boundary
// CHECKPOINT: "Pre-migration baseline"
// - All tests passing
// - Production code stable
// - Database schema v1
// Phase 1: Add new columns (backward compatible)
// CHECKPOINT: "New columns added"
await db.schema.alterTable('users', (table) => {
table.jsonb('preferences').nullable();
table.timestamp('last_active').nullable();
});
// Phase 2: Migrate existing data
// CHECKPOINT: "Data migrated"
const users = await db.select().from('users');
for (const user of users) {
await db.update(users)
.set({
preferences: migrateUserPrefs(user),
last_active: user.updated_at
})
.where(eq(users.id, user.id));
}
// Phase 3: Update application code
// CHECKPOINT: "Application updated"
class UserService {
async updatePreferences(userId: string, prefs: Preferences) {
// New implementation using preferences column
return db.update(users)
.set({ preferences: prefs })
.where(eq(users.id, userId));
}
}
// Phase 4: Remove old code paths
// CHECKPOINT: "Old code removed"
// Only checkpoint here if all tests pass
// Phase 5: Drop deprecated columns
// CHECKPOINT: "Migration complete"
// Final checkpoint before marking migration doneSession boundaries matter more than developers expect. A four-hour refactoring session should have checkpoints roughly every 30-45 minutes—not because the agent needs breaks, but because context drift accumulates. The agent's understanding of the codebase evolves as it works. Periodic checkpoints capture these evolution stages.
The three-checkpoint rule provides a safety net for exploratory work: maintain at minimum a baseline checkpoint, a mid-point checkpoint, and a latest checkpoint. If exploration fails, rewind to mid-point. If mid-point also failed, rewind to baseline. This layered approach prevents losing all progress when experiments don't pan out.
Test-driven checkpoint strategies work particularly well for TDD workflows. Checkpoint after each green test suite. The agent makes changes, runs tests, fails. Rewind to last green state, try different approach. This creates a ratchet effect—progress only moves forward when tests confirm correctness.
Context window management integrates with checkpoints. When the conversation history grows large, create a checkpoint, then start a fresh session with a summary of decisions made. The checkpoint preserves the full context if needed, but the new session runs with a clean context window. This matters for sessions approaching token limits.
The practical reality is that most developers underuse manual checkpoints. They rely entirely on automatic snapshots, then discover the automatic checkpoint they need expired 10 changes ago. Production teams build checkpoint discipline: explicit snapshots at phase boundaries, not just reliance on automatic capture.
Checkpoint-Based Recovery Patterns: Rollback vs Selective Restore
Two fundamentally different recovery patterns emerge from checkpoint systems: full rollback and selective restore. Full rollback returns to a previous state completely—code, conversation, everything. Selective restore cherry-picks elements from different checkpoints. The choice determines recovery speed and preserved work.
Full rollback serves catastrophic failures. The agent's last twenty changes broke everything, tests are red across the board, the codebase is in an unknown state. Don't debug. Don't try to salvage. Rewind to the last known-good checkpoint and start over with better direction. This pattern prioritizes certainty over preserving work.
flowchart LR
subgraph "Full Rollback Pattern"
FullStart("Known good state") --> Changes1("Agent makes changes")
Changes1 --> Disaster("Everything breaks")
Disaster --> FullRewind("Complete rollback")
FullRewind --> FullStart
end
subgraph "Selective Restore Pattern"
SelectStart("Mixed state") --> Analyze("Identify good vs bad changes")
Analyze --> Cherry("Cherry-pick good changes")
Cherry --> Discard("Discard bad changes")
Discard --> Combined("Combined safe state")
end
style Disaster stroke:#ef4444,fill:#450a0a,color:#fca5a5
style FullRewind stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
style Combined stroke:#34d399,fill:#0b3b2e,color:#d1fae5
Selective restore handles partial failures. The agent refactored authentication (good), updated the session manager (good), and rewrote the permission checker (broken). Full rollback loses the authentication and session work. Selective restore keeps those, reverts only the permission checker. Time saved: 45 minutes.
The selective pattern requires understanding what checkpoint elements are independent. File changes in different modules can usually be separated. Conversation context typically must stay intact—you can't restore code from checkpoint 5 while keeping conversation from checkpoint 12 without creating confusion. The agent's reasoning must match its code state.
Checkpoint diffing reveals dependencies between changes. Before doing selective restore, engineers preview what each checkpoint modified. If checkpoint B depends on changes from checkpoint A, restoring B without A creates breakage. The preview system shows these dependencies through file edit chains.
The recovery decision tree works like this:
// Recovery pattern decision logic
interface RecoveryStrategy {
assessDamage(): 'catastrophic' | 'partial' | 'cosmetic';
selectPattern(): 'full-rollback' | 'selective-restore' | 'manual-fix' {
const damage = this.assessDamage();
if (damage === 'catastrophic') {
// Multiple systems broken, unknown state
// Full rollback to last stable checkpoint
return 'full-rollback';
}
if (damage === 'partial') {
// Some changes good, some bad, clear boundaries
// Selective restore to keep good work
return 'selective-restore';
}
// Single file issue, clear fix
// Faster to fix manually than restore
return 'manual-fix';
}
}
// Example: selective restore after mixed session
class CheckpointManager {
async selectiveRestore(session: Session) {
// Keep authentication refactor from checkpoint 3
await this.restoreFiles(['auth.ts', 'auth.test.ts'], 3);
// Keep session updates from checkpoint 4
await this.restoreFiles(['session.ts', 'session.test.ts'], 4);
// Discard permission changes from checkpoint 5
// Conversation context maintained from checkpoint 4
// Agent can retry permission logic with context intact
}
}Production patterns favor selective restore for long sessions. A three-hour refactoring session with 40 checkpoints likely has value scattered throughout. Full rollback wastes hours. Selective restore salvages the good work, discards only the failures. The time economics are clear.
The failure mode developers miss: over-relying on selective restore when full rollback is appropriate. Trying to salvage broken changes wastes time. If the session went badly wrong, starting fresh from baseline is faster than attempting surgical restoration. Checkpoint discipline means knowing when to cut losses.
Integrating Checkpoints with Git Stash and Pre-Agent Snapshots
Checkpoints operate at session level. Git operates at commit level. The gap between them creates risk—agent changes that never reach Git can't be recovered if the session crashes. Production teams bridge this gap by integrating checkpoint strategies with Git stash and pre-agent snapshots.
The layered safety pattern starts before the agent touches code. Create a Git stash of current work, commit any uncommitted changes to a WIP branch, then launch the agent. This establishes a Git-level baseline independent of Claude Code's checkpoint system. If the entire Claude Code session crashes, Git preserves the pre-agent state.
// Pre-agent snapshot script
// Run before starting autonomous sessions
import { execSync } from 'child_process';
interface PreAgentSnapshot {
createBaseline(): void;
verifyCleanState(): boolean;
recordSessionStart(): void;
}
class GitSafetyNet implements PreAgentSnapshot {
createBaseline(): void {
// Stash any uncommitted work
execSync('git stash push -m "Pre-agent baseline"');
// Create safety branch from current HEAD
const timestamp = new Date().toISOString();
const branchName = `agent-session-${timestamp}`;
execSync(`git checkout -b ${branchName}`);
// Commit current state as baseline
execSync('git add -A');
execSync('git commit -m "Agent session baseline" --allow-empty');
console.log(`Safety baseline created: ${branchName}`);
}
verifyCleanState(): boolean {
const status = execSync('git status --porcelain').toString();
return status.trim() === '';
}
recordSessionStart(): void {
// Log session metadata for recovery
const metadata = {
branch: execSync('git branch --show-current').toString().trim(),
commit: execSync('git rev-parse HEAD').toString().trim(),
timestamp: new Date().toISOString(),
stash: execSync('git stash list').toString().trim()
};
console.log('Session metadata:', JSON.stringify(metadata, null, 2));
}
}
// Usage before agent session
const safety = new GitSafetyNet();
safety.createBaseline();
safety.recordSessionStart();
// Now launch Claude Code agentThe periodic Git checkpoint pattern complements Claude Code checkpoints for very long sessions. Every 60-90 minutes of agent work, create a Git commit on the safety branch. This provides recovery points that survive session crashes. The commits don't need to be clean—they're safety checkpoints, not production commits.
Stash integration enables quick experiments. Agent wants to try a risky refactor? Stash current session state, let it experiment, evaluate results. If it works, pop the stash and integrate. If it fails, rewind Claude Code checkpoint and pop the stash to restore pre-experiment state. Two layers of undo.
The production workflow combines both systems:
Git baseline → Claude Code session with auto-checkpoints → Periodic Git snapshots → Session complete → Squash all safety commits into clean feature commits. The safety infrastructure disappears in the final Git history, but it provided protection throughout development.
Context handoff between sessions requires Git integration. Agent session ends, developer needs to continue tomorrow. The in-memory checkpoints are gone. But if the session periodically committed to the safety branch, the developer can review the commit history to understand what the agent did. Git log becomes the checkpoint timeline for cross-session work.
The recovery hierarchy becomes:
- Claude Code checkpoint (fastest, session-only)
- Git safety branch commits (survives crashes, needs cleanup)
- Git stash (pre-agent baseline, nuclear option)
- Feature branch (last resort, manual recovery)
Teams that skip Git integration learn the hard way when Claude Code crashes mid-session. All checkpoint state disappears. Only Git commits survive. The lesson is expensive: always maintain Git-level baselines for work that matters.
Production Patterns: When to Clear Context vs Rewind vs Start Fresh
Three distinct recovery strategies handle different failure modes: clear context, rewind checkpoint, or start fresh session. The choice depends on whether the problem is bad direction, bad execution, or context corruption. Production teams develop decision frameworks to choose correctly under pressure.
Clear context preserves all code changes but resets conversation history. Use this when the agent's direction is wrong but its recent edits are fine. The code is good, the trajectory is bad. Clear context, provide new direction, continue with the same code state. This pattern salvages work while correcting course.
flowchart LR
Problem("Agent pursuing wrong approach") --> Assess("Assess code vs direction")
Assess --> CodeGood("Code changes are sound")
CodeGood --> ClearCtx("Clear conversation context")
ClearCtx --> NewDirection("Provide corrected direction")
NewDirection --> Continue("Continue with same codebase")
Assess --> CodeBad("Code changes are broken")
CodeBad --> Rewind("Rewind to previous checkpoint")
Rewind --> Redirect("Redirect with context intact")
Assess --> Unknown("State completely unclear")
Unknown --> Fresh("Start fresh session from Git baseline")
Fresh --> Review("Review all changes manually")
style ClearCtx stroke:#7c9cf0,fill:#142544,color:#eaf2ff
style Rewind stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style Fresh stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
Rewind checkpoint preserves conversation context but reverts code. Use this when execution failed but direction was correct. The agent understood the goal, attempted the right approach, but the implementation has bugs. Rewind to pre-implementation checkpoint, clarify the specific issue, let it retry with conversation context intact.
Start fresh abandons both code and conversation. Use this when context corruption makes the session unreliable. The agent is hallucinating about what code exists, referencing files that were deleted, or maintaining contradictory beliefs about system state. No amount of rewinding fixes context corruption. Start over.
The decision framework:
// Production recovery decision system
interface SessionState {
codeQuality: 'good' | 'fixable' | 'broken';
directionCorrect: boolean;
contextValid: boolean;
timeSinceBaseline: number; // minutes
}
class RecoveryDecision {
choose(state: SessionState): 'clear-context' | 'rewind' | 'fresh-session' {
// Context corruption overrides everything
if (!state.contextValid) {
return 'fresh-session';
}
// Good code, wrong direction
if (state.codeQuality === 'good' && !state.directionCorrect) {
return 'clear-context';
}
// Broken code, correct direction
if (state.codeQuality === 'broken' && state.directionCorrect) {
return 'rewind';
}
// Session too long, uncertainty accumulating
if (state.timeSinceBaseline > 120) {
return 'fresh-session';
}
// Fixable code, any direction
if (state.codeQuality === 'fixable') {
return 'rewind';
}
// Default to fresh session when uncertain
return 'fresh-session';
}
execute(action: 'clear-context' | 'rewind' | 'fresh-session', state: SessionState): void {
switch(action) {
case 'clear-context':
console.log('Preserving code, resetting conversation');
// Clear conversation, keep files
// Provide new direction
break;
case 'rewind':
console.log(`Rewinding to checkpoint from ${state.timeSinceBaseline}min ago`);
// Open /rewind menu
// Select appropriate checkpoint
// Redirect with preserved context
break;
case 'fresh-session':
console.log('Starting fresh session from Git baseline');
// Commit current state to safety branch if any value
// Close Claude Code
// Review changes manually
// Start new session with lessons learned
break;
}
}
}The time factor matters more than developers expect. Sessions longer than two hours accumulate context drift regardless of checkpoint quality. The agent's internal model of the codebase diverges from reality. Starting fresh every 2-3 hours prevents this drift from becoming critical.
Clear context is underutilized. Developers rewind when they should clear context, losing good code because conversation went wrong. The distinction is critical: rewind for bad code, clear context for bad direction. Mixing these up wastes work.
Fresh sessions feel expensive but often save time. Developers spend 30 minutes trying to salvage a corrupted session when starting fresh would have solved the problem in 10 minutes. The sunk cost fallacy applies to checkpoint state just like production code.
Production patterns establish session length limits. No autonomous session should run longer than 90 minutes without a decision checkpoint: continue with current context, start fresh, or commit progress and take manual control. This forced evaluation prevents runaway sessions that become unrecoverable.
The failure mode teams encounter: treating all problems as checkpoint/rewind problems. Sometimes the issue is the task definition, not the execution. Rewinding and retrying the same broken task ten times wastes hours. Recognize when the approach itself is wrong and start fresh with better requirements.
Frequently Asked Questions
How long do Claude Code checkpoints persist?
Checkpoints exist only for the current session and clear when you close Claude Code. The system stores up to 50 automatic checkpoints in memory by default, typically covering 2-3 hours of work. For longer sessions, integrate with Git commits to create persistent recovery points beyond session boundaries.
Can you restore checkpoints after a Claude Code crash?
No—in-memory checkpoints disappear when the session crashes. This is why production teams create Git safety branches before starting autonomous sessions. Commit to the safety branch every 60-90 minutes so crashes don't lose all progress. Checkpoints serve immediate recovery, Git serves crash recovery.
What's the difference between /rewind and Esc?
Esc stops the agent mid-action while preserving full context—you can redirect without losing conversation or code state. /rewind or Esc + Esc opens the checkpoint timeline to restore a previous state, reverting both code and conversation to that point. Use Esc to interrupt and redirect, /rewind to undo changes.
Should you checkpoint before every risky agent task?
Yes, create manual checkpoints before major refactors, architectural changes, or experimental approaches. While Claude Code checkpoints automatically before file changes, explicit checkpoints at logical boundaries give you named restore points. Think "Pre-migration baseline" or "Before authentication refactor"—these make recovery decisions faster under pressure.
How do selective restores work with conversation context?
Selective file restores keep conversation context from the target checkpoint—you can't mix code from checkpoint 5 with conversation from checkpoint 8 without creating confusion. The agent's reasoning must match its code state. If you need to keep specific files but reset direction, restore those files then clear conversation context and provide new direction.
Conclusion: Checkpoints as the Foundation for Reliable Long-Running Agents
The checkpoint system transforms autonomous agents from fragile experiments into production tools. Engineers who master checkpoint patterns ship faster because they trust agents to explore without permanent consequences. The recovery path is always two seconds away.
The critical insight is that checkpoints enable aggressive autonomy. Let the agent try risky refactors. Let it explore alternative implementations. Let it run for hours without supervision. The checkpoint safety net catches failures before they become expensive. This psychological shift—from cautious supervision to confident delegation—is where productivity gains materialize.
Production teams that ignore checkpoint discipline pay the cost in lost work and wasted time. Every hour-long session without manual checkpoints at phase boundaries risks losing everything to a single catastrophic edit. Every multi-hour session without Git integration risks losing everything to a crash.
That covers the essential patterns for checkpoint-based agent recovery. Apply these in production and the difference will be immediate. Your autonomous sessions will run longer, recover faster, and ship more value. The foundation is there—use it.