Chapter 19. Claude Code Checkpoints, Rewind, and What They Do Not Restore
Claude Code can undo its own file edits: it captures a checkpoint
before each user prompt, and /rewind puts the files, the
conversation, or both back to an earlier point. It does not restore
files moved by bash commands, edits made by subagents, paths that turn
out to be symlinks, work from a concurrent session, or anything that
left the machine. An agent edits files faster than I read diffs, and
some fraction of those edits are wrong. By the time I notice, two or
three prompts of new work sit on top of the mistake. I trust the
checkpoint for one job, undoing the agent’s own file edits inside one
session, and the value of that trust depends on knowing the edges.
What a checkpoint captures and how long it lasts
Claude Code captures a checkpoint before each user prompt and keeps file snapshots for the 100 most recent checkpoints in a session. The unit of undo is the prompt. Rewinding to a checkpoint returns the tracked files to their state before that prompt ran, which means a single prompt that made ten edits and fired a deploy has no interior restore points: the boundary sits before the whole prompt or not at all.
The 100-snapshot window shapes long sessions. A session past its hundredth prompt sheds restore points at the far end while adding them at the near end, so the deep history of a marathon session is conversation to reread, not state to restore. Work I might want to return to from that far back belongs in a commit, not a checkpoint.
Checkpoints are saved with the conversation, so a session I resume
tomorrow can still /rewind to points from today. They are
not permanent. Claude Code cleans up checkpoints along with their
sessions after 30 days, and the cleanupPeriodDays setting
moves that window. Snapshot storage gets pruned as checkpoints go:
discarding an older checkpoint deletes the snapshot files no remaining
checkpoint references, except each file’s first snapshot, which the VS
Code extension keeps as the baseline for session diffs. Before v2.1.208,
superseded snapshots stayed on disk until session cleanup.
The /rewind menu: six actions and two ways to open it
/rewind opens the rewind menu, and so does pressing
Esc twice when the prompt input is empty. With text in the
input, double Esc clears the text instead and sends it to
input history, so a stray double-tap costs a paste rather than a
retype.
The menu offers six actions: Restore code and conversation, Restore conversation, Restore code, Summarize from here, Summarize up to here, and Never mind. The two summarize actions manage conversation length from the same menu; the three restore actions are the undo. The code-restore options appear only when the selected checkpoint has tracked file changes, and that visibility rule doubles as a diagnostic. When I know a stretch of work changed files but the code options are missing at its checkpoint, the edits came from somewhere checkpointing does not track: a bash command, or a subagent running in the background.
The code/conversation split earns its place. Restore conversation alone fits the case where the files are right but the context went sideways: the agent argued itself into a bad frame and I want a clean transcript over the same code. Restore code alone fits the reverse, a discussion worth keeping wrapped around edits that are not. Restore both when the whole stretch was a dead end.
/clear is not the wall it appears to be. If
/clear ran earlier in the same Claude Code process, the
rewind menu shows a top entry labeled
/resume <session-id> (previous session); it requires
v2.1.191 or later and stays available until I exit or resume a different
session.
Edits that checkpointing does not track
Rewind restores what checkpointing tracked, and checkpointing tracks one thing: edits made through Claude’s file editing tools, within the current session. Each clause in that sentence excludes something.
Bash commands are outside it. Files modified by rm,
mv, cp, a build script, or a shell one-liner
are not tracked, and rewind cannot undo them. A session that edits a
file with the Edit tool and then renames it with mv has
produced a change rewind can only half-see: the edit is in a snapshot,
the rename is not.
Subagent edits are outside it. They land beyond the session’s
checkpoints, so rewind does not restore them; that includes a background
/code-review --fix run and any forked skill running in the
background. The exception is a context: fork skill running
in the foreground, whose edits restore like the session’s own. The
default under that exception moved. As of v2.1.218 a forked skill runs
in the background by default, with background: false in its
frontmatter as the pin back to the foreground; before v2.1.218 forked
skills ran in the foreground. A skill whose edits rewound before an
upgrade can stop rewinding after it, with no change to the skill
itself.
Links are a hazard with a version gate. Rewind skips tracked paths
that are symlinks or hard links and reports
Restored the code, but skipped N files; the skipped files
keep their current contents. That is the documented behavior as of
v2.1.216. Before that release, /rewind wrote and deleted
through links at tracked paths without warning. This machine runs
2.1.211, the wrong side of the gate, so a restore here still writes
through the link. Where skipping applies, turning on /debug
before a restore records each skipped path in
~/.claude/debug/<session-id>.txt, which turns
“skipped N files” from a shrug into a list I can act on.
Other sessions are outside it. Checkpointing tracks files edited within the current session; manual edits made outside Claude Code and edits from other concurrent sessions are not captured unless they touch the same files. That caveat cuts the wrong way. When two sessions edit the same file, Restore code in either one writes its snapshot over whatever the file holds at that moment, including the other session’s finished work. Rewind has no concept of “someone else was here”.
Why a restore cannot undo a deploy or a migration
A checkpoint is a set of file snapshots and a restore writes files, which leaves everything a session does that is not a file edit outside the boundary. That is the entire mechanism, and it puts the case I care most about outside the checkpointing docs. The deploy a prompt kicked off is still serving traffic after the rewind. The migration ran, and the rows hold whatever it made of them. The webhook stays registered, the sent email stays sent, the rotated key stays rotated.
The failure mode is not that rewind misses these; I don’t expect an undo button to recall a deploy. The failure mode is the mismatch a restore leaves behind. After Restore code and conversation, the working tree claims the deploy never happened, and the transcript that would have explained the difference is gone with it. Production disagrees with both, and the session that could reconcile them has forgotten the whole episode.
Two rules cover this. Rewind before side effects leave the machine, while the blast radius is still the working tree. After a deploy or a migration has run, stop treating rewind as an option and roll forward in git instead: a revert commit, a fresh deploy, a fix that leaves a record instead of erasing one.
Checkpoint, worktree, commit: three scales of undo
A checkpoint is session-scale undo. Its unit is the prompt, its snapshot window is the 100 most recent checkpoints, its lifetime is the session plus the 30-day cleanup, and its coverage is the session’s own tracked edits. Inside that box it beats git on friction: no staging, no commit message, and the conversation restores alongside the code, which git cannot do at all.
The two systems meet in the working tree. A code restore is an
ordinary write as far as git is concerned: after Restore code, the
reverted files show up as modified, the same as any other edit. That
gives me a cheap audit. Commit before the risky stretch, restore when
the stretch goes wrong, and git diff afterward should come
back empty. When it does not, the remainder is the part rewind could not
reach, bash-moved files and background-subagent writes included, and the
diff is the cleanup list.
A worktree is task-scale isolation. I run concurrent sessions on one
machine, and the shared-file caveat above is the collision worktrees
exist to prevent: sessions sharing a checkout share files, and one
session’s restore can overwrite another session’s work. One worktree per
task means a rewind’s blast radius ends at the task boundary, because no
shared files are left to fight over. The sandbox is built for the same
arrangement. When the working directory is a linked git worktree,
sandboxed commands can write to the main repository’s shared
.git directory so git commit can update refs
and the index, while writes to hooks/ and
config inside it stay denied. Committing from an isolated
worktree works under the sandbox; rewiring the repository’s plumbing
from one does not.
A commit is the durable record. Git does not care which tool changed the tree: bash moves, subagent writes, another session’s edits, another machine’s push, all of it lands in the next commit. It has no 100-checkpoint window and no 30-day expiry, and it is the only artifact of the three that leaves the machine. A checkpoint dies with its session files, a worktree dies with its checkout, a pushed commit survives the laptop. I treat checkpoints as the convenience layer between commits, not as version control, because that is what the mechanism is.
Rewind behavior by version, and where 2.1.211 sits
This Mac runs Claude Code 2.1.211, checked 2026-07-27, and rewind behavior shifted across recent releases. The docs describe the newest. What matters at the keyboard is which side of each gate the installed binary sits on.
| Version | Change | On 2.1.211 |
|---|---|---|
| v2.1.191 | Rewind menu offers
/resume <session-id> (previous session) after a
/clear in the same process |
Available |
| v2.1.208 | Superseded snapshots deleted once no remaining checkpoint references them | Available |
| v2.1.216 | Rewind skips symlink and hard-link paths instead of writing through them | Not here; restores still write through links |
| v2.1.218 | Forked skills run in the background by default, moving their edits outside checkpoints | Not here; forked skills still run foreground and their edits still rewind |
The last two rows pull in opposite directions across an upgrade. Crossing 2.1.216 makes restores safer around links. Crossing 2.1.218 shrinks what rewind covers, because a forked skill’s edits stop counting as the session’s own, and nothing in the session transcript announces the change.
The four rules I run
- Commit before handing a session a risky stretch. Rewind covers the session’s tracked edits inside the 100-checkpoint window; the commit covers the whole tree, including whatever bash commands and subagents did to it.
- Rewind before side effects leave the machine. Once a deploy or migration has run, the fix is a roll-forward in git, not a restore that makes the working tree lie about what happened.
- Do not rewind in a shared checkout. Work in a worktree, so the question of whose edits a restore would clobber never has to be asked.
- Read
Restored the code, but skipped N filesas a partial restore. Diff before continuing, and when a restore matters, turn on/debugfirst so the skipped paths land in~/.claude/debug/<session-id>.txt.
A checkpoint undoes the agent’s edits inside one session, and that is the whole contract. The durable undo lives in git, and the space between the two is where a clean-looking tree ends up sitting next to a production surface no file on disk describes.