Skip to content

AI CODING ASSISTANTS

Claude Code Checkpoints: What Rewind Can and Cannot Restore

Claude Code checkpoints are whole-file copies of what its edit tools touched. We audited 771 of them and found 39% hold states that exist in no git commit.

Claude Code checkpoints are whole-file copies of everything its edit tools touched, written to ~/.claude/file-history and indexed from the session transcript. We audited the store on a machine with 25 days of daily use — 74 session directories, 771 snapshots, 58.66 MB — and compared every one of them against git. The headline is the gap: 131 of 335 checkpointed states exist in no commit, and 7,081 shell invocations produced no checkpoint at all. Measured 2026-08-31 on Claude Code 2.1.251.

Key takeaways

  • A checkpoint is a whole-file copy, not a diff — mean 79,776 bytes, named <path-hash>@v<n> under a per-session directory.
  • Coverage is partial by design: 948 checkpoint records against 2,178 edit-tool calls, and zero against 7,081 Bash and PowerShell calls.
  • 74 of 165 sessions have a checkpoint directory at all. A session that edited nothing records a checkpoint with an empty manifest and stores no file.
  • 131 of 335 states (39.1%) match no commit in any of the five repositories checked — that is the value of the store and the reason it is not a git substitute.
  • The store answers to a 30-day sweep, so it is recovery, not history.

What a checkpoint is on disk

Anthropic's checkpointing documentation says every user prompt creates a checkpoint capturing the state of your code before it — an automatic behaviour of the session model described in the complete Claude Code guide, not something you switch on. On disk that becomes one directory per session, holding one file per tracked path per version:

Terminal
ls ~/.claude/file-history/02b2d588-0eac-42ad-aab7-70ad72feae4c
# → 1ffb4e4c5a7b1a59@v1   16727
# → 1ffb4e4c5a7b1a59@v2   17233
# → 4d20606d5d80b73d@v2   16225
# → 8f7a36ad2b5cdad1@v1   20971

The name is a 16-character hash of the file's path plus a version suffix. The contents are the file, verbatim — open one and you get readable source, not a patch. That is why the store is large relative to what it protects: 58.66 MB across 771 snapshots, a mean of 79,776 bytes each, for files that are mostly a few kilobytes of text each time they change.

Versions climb per path within a session, and they climb slowly:

VersionSnapshots
@v1392
@v2306
@v351
@v416
@v54
@v62

Ninety per cent of the store is a file's first or second saved state. Nothing here reached a seventh. That shape follows from the documented retention rule — within a session Claude Code keeps snapshots for the 100 most recent checkpoints and discards files no retained checkpoint still references, keeping each file's first snapshot as a baseline.

How the store is indexed

The store on its own is unusable: hashed names, no paths. The mapping lives in the transcript, in two record types that the session store writes alongside the conversation.

  • file-history-snapshot — one per checkpoint, keyed by the message id of the prompt that created it, carrying a trackedFileBackups manifest of every tracked path and the exact snapshot file holding its state at that moment. 301 records, 107 of them with a non-empty manifest, 1,647 tracked entries in total.
  • file-history-delta — one per tracked write, carrying the trackingPath, the backupFileName, and a backupTime. 948 records.

The manifest is what makes "rewind to this prompt" possible: it is a complete picture of the tracked world at one message, so restoring is a lookup rather than a replay. And it is the only complete picture — the delta records name just 225 of the 559 distinct snapshot files on disk. Read only the deltas and 60% of the store is unreachable.

Terminal
npm run check:checkpoints
# → store         : 74 session dirs · 771 snapshots · 58.66 MB
# → index records : 301 snapshots (107 with a manifest) · 948 deltas
# → coverage      : 948 deltas / 2,178 edit calls / 7,081 shell calls
# → vs git        : 131 of 335 states exist in no commit

Every one of the 559 names the transcripts reference resolves to a file that is still on disk. Whatever else is uncertain here, the store is internally consistent.

Claude Code checkpoint store audit showing coverage against edit calls, shell calls and git commits
What the checkpoint store covers, and what it does not, across 165 sessions.

How much of a session checkpoints cover

The documented rule — a checkpoint per prompt — holds. In the 97 sessions that produced any checkpoint record, there are 301 checkpoints against 342 user prompts, and in 73 of those 97 sessions the two counts are identical. The gap is a counting definition on our side, not a missing checkpoint.

What the rule does not tell you is how much of the session's actual change is captured, and that is where the numbers get interesting:

ActivityCallsCheckpoint records
Edit1,574
Write604
Edit tools combined2,178948 (43.5%)
Bash + PowerShell7,0810

Two separate things are going on. The shell row is documented behaviour: Anthropic's limitations section says checkpointing does not track files modified by bash commands, and on this machine that exclusion covers the single busiest tool by a factor of three. The edit row is subtler — a delta is written when a tracked path's state changes, not once per tool call, so repeated edits to the same file inside one checkpoint collapse into one record.

There is a third number worth having. 74 of 165 sessions have a checkpoint directory, but 97 sessions have checkpoint records. The 23-session difference is sessions where every checkpoint had an empty manifest: nothing was edited, so nothing was stored. A checkpoint existing does not mean a file was saved.

What rewind cannot undo

Put the measurement next to the documented limitations and the boundary is sharp. Rewind restores files that Claude's edit tools changed in this session, and the following fall outside that:

  • Anything the shell did. rm, mv, a build step that rewrites a file, a script Claude ran. 7,081 calls here, zero coverage.
  • Most subagent edits. A background subagent's edits are not captured in your session's checkpoints; git is the recovery path for those.
  • Changes from outside the session. Your own edits in another editor, and edits from a concurrent session, unless they happen to touch the same files.
  • Symlinked and hard-linked paths. A restore skips them and warns rather than rewriting through the link.
  • Anything past the retention window. The store is swept with its session once older than cleanupPeriodDays, default 30.

For the keyboard path — /rewind, or Esc twice on an empty prompt — and the rest of the interactive surface, the Claude Code command reference has the catalogue, and the complete guide has the session model these commands act on.

Two in five states exist in no commit

The obvious question about a second copy of your files is whether it is telling you anything git does not. So we asked it directly: take every checkpoint file that maps to a path inside a git repository, and compare it byte-for-byte against every commit that ever touched that path.

RepositoryStates comparedMatch a commitIn no commit
Repo A21215755
Repo B56749
Repo C301812
Repo D19136
This repository1899
Total335204131

131 of 335, or 39.1%, are states that appear in no commit — and every repository contributed some. These are working-tree moments between commits: the file as it stood before the second edit of an afternoon, the version that existed for eleven minutes and was then rewritten.

That is both the argument for checkpoints and the argument against treating them as history. The .claude directory reference lists file-history/<session>/ among the paths the retention sweep removes, which is what puts a clock on all 131 of them. They cover precisely the window git cannot — after the last commit, before the next one — and they cover it for 30 days, after which the sweep takes them with the session.

A worked example from this repository

One file, traced end to end. content/ai-coding-assistants/claude-code-plan-mode.mdx is a published article on this site, edited by Claude in a session on 2026-08-06:

StateSizeWhat it is
1ffb4e4c5a7b1a59@v116,727 BThe file as it stood before that session's first edit
1ffb4e4c5a7b1a59@v217,233 BAfter the retro-link pass in the same session
Working tree today17,600 BThe current file
7 git commits15,543–17,318 BEvery committed version of the path

Diffing @v1 against @v2 shows the actual edit — updatedIso moving from 2026-08-05 to 2026-08-06, and three paragraphs gaining internal links. Both snapshots are readable MDX, both restore cleanly.

Neither matches any of the seven commits. The checkpoint store on this machine is holding two states of a published article that exist nowhere in the repository's history, three and a half weeks after they were written. That is the finding in miniature: useful, real, and on a timer.

What we got wrong reading the records

Two things, and the first would have shipped as a wrong sentence.

backupFileName: null does not mean "no backup was written." The first reading was that a null name is a failure — a tracked file with nothing behind it, unrecoverable. It is not. Null appears in manifests alongside version: 2 and version: 3, on files that had been edited repeatedly. It records absence as a state: the file did not exist at that version. Restoring to a null version deletes the file, which is the correct undo for a file Claude created. That reading explains the distribution — 501 of 717 tracked paths only ever record an absence, because most tracked paths in this corpus are files Claude wrote from scratch and never revised, and 554 of 717 have an absence as their first entry.

A rewind cannot be observed from here. Nothing in the transcript format records one, and claude --help on 2.1.251 names neither checkpoints nor rewind — the interactive surface is the only place they appear. So every claim in this article is about the store a rewind reads from, not about a restore we watched happen. The script header carries that as a WHAT THIS IS NOT block.

One more thing worth knowing before you rely on the store: 215 of the 948 deltas point at scratchpad files under the system temp directory. A fifth of the checkpoint traffic here is protecting throwaway analysis scripts. That is harmless, and it means the store's size is a poor proxy for how much of your project is covered.

Best practices

  • 1. Commit before a session that will edit a lot. It converts the whole session into one revertible unit and gives rewind a floor to land on, especially when running Claude Code auto mode for autonomous multi-file changes.
  • 2. Run git status after every restore. Restoring code touches tracked files only; anything the shell did is still there and the restore will not mention it.
  • 3. Rewind early rather than accurately. Restoring to the prompt before things went wrong is cheap; reconstructing which of six files changed is not.
  • 4. Treat 30 days as the real limit. cleanupPeriodDays takes checkpoints with the session. Anything you want past a month belongs in a commit.
  • 5. Keep the conversation and the code restores separate in your head. They are different menu options for a reason — restoring one without the other is usually what you want when only the code went wrong.

Common mistakes

  • Mistake 1: expecting rewind to undo a shell command. It never has and the documentation says so; the measurement here is that the shell is the majority of what happens in a session. Symptom: a restore reports success and the build is still broken.
  • Mistake 2: assuming a checkpoint means a saved file. Twenty-three sessions here recorded checkpoints and stored nothing, because nothing was edited through the edit tools.
  • Mistake 3: using checkpoints as version history. They are session-scoped and swept after 30 days. The 131 never-committed states in this audit are all on that clock.
  • Mistake 4: reading the store directly. The filenames are path hashes; without the transcript manifest you cannot tell which file a snapshot is. Use /rewind and let the index do it.
  • Mistake 5: assuming the store is your project. A fifth of the deltas here protect temporary scratch files, not source.

Conclusion

Use checkpoints for what they are: a per-prompt safety net over the files Claude's edit tools touched, covering the window between commits, expiring in 30 days. Rewind the moment a session goes wrong rather than trying to reconstruct it, then check git status, because everything the shell did survived the restore. And keep committing — not because checkpoints are unreliable, but because 39% of what this store held existed in no commit, and in a month none of it will exist anywhere. For what else the same directory keeps, see where Claude Code stores history; for the other control people reach for when a session goes sideways, what clearing context actually removes.

Frequently asked questions

Where are Claude Code checkpoints stored?
In ~/.claude/file-history, one directory per session id, holding whole-file copies named by a 16-character path hash and a version suffix, like 1ffb4e4c5a7b1a59@v2. On this machine that is 74 session directories, 771 snapshot files and 58.66 MB. The index that maps those files back to real paths lives in the session transcript, not in the store.
How do I rewind changes in Claude Code?
Run /rewind, or press Esc twice with an empty prompt input, to open the rewind menu. It lists each prompt in the session and offers to restore code, the conversation, or both. The code-restore options appear only when the selected checkpoint has tracked file changes to revert.
Does Claude Code checkpointing undo changes made by bash commands?
No. Anthropic's documentation states plainly that checkpointing does not track files modified by bash commands, and the measurement matches: 7,081 shell invocations in this corpus produced zero checkpoint records. On this machine the shell is the busiest writer by a factor of three, and none of it is covered.
Are Claude Code checkpoints a replacement for git?
No, and the numbers explain why it is still worth having both. Of 335 checkpoint states compared byte-for-byte against every commit that touched their path, 204 matched a committed version and 131 did not. Checkpoints hold intermediate working-tree states git never saw, which is exactly the window git cannot recover for you.
How long do Claude Code checkpoints last?
They are deleted with their session after cleanupPeriodDays, which defaults to 30. Within a session, Claude Code keeps snapshots for the 100 most recent checkpoints and drops files no retained checkpoint references, except each file's first snapshot. Nothing on this machine has aged out yet — the store is 24.8 days old.

Muhammad Kashif

Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.