🔍 Deep Dive 📅 April 3, 2026 ⏱️ 8 min read

Claude Code vs Cursor: What Your AI Coding Tools Store Locally

One stores everything as plain-text JSONL. The other spreads data across SQLite databases, global state blobs, and checkpoint systems. A side-by-side comparison of how Claude Code and Cursor handle local storage — and why it matters.

Run these two commands:

du -sh ~/.claude/
du -sh ~/.cursor/ ~/Library/Application\ Support/Cursor 2>/dev/null

On my machine, Claude Code weighs in at 858 MB. Cursor? 2.1 GB in ~/.cursor/ plus another 4.9 GB in Application Support — 7 GB total.

Both tools record everything: your prompts, the AI’s responses, tool calls, file edits, thinking traces. But they store it in fundamentally different ways.

I spent weeks reverse-engineering both systems while building vibe-replay. Here’s what I found.


The one-sentence summary

Claude Code = one JSONL file per session. Readable, greppable, done.

Cursor = a distributed storage system across SQLite databases, JSONL transcripts, global state blobs, workspace DBs, and checkpoint diffs. Powerful, but not something you casually inspect.


Session storage: text files vs. a database stack

Claude Code

Every session is a single JSONL file in ~/.claude/projects/:

~/.claude/projects/<project-hash>/<session-id>.jsonl

Each line is a JSON object — a user message, an assistant response, a tool call, a system event. You can cat it, jq it, pipe it through anything.

129 sessions on my machine. That’s 129 files. Simple.

Cursor

Cursor has at least three primary storage layers:

LayerLocationFormat
Chat databases~/.cursor/chats/*/*/store.dbSQLite
Transcript files~/.cursor/projects/*/agent-transcripts/*.jsonlJSONL
Global state~/Library/Application Support/Cursor/User/globalStorage/state.vscdbSQLite (1.24 GB)

On my machine, that’s 171 SQLite chat databases, 138 transcript JSONL files, and a global state.vscdb with over 88,000 key-value entries just in the agentKv family.

The critical detail: these layers don’t share a universal session ID. My store.db session IDs and composerData session IDs were completely disjoint. Cursor effectively has two separate replay stacks, and transcript files can attach to either one.


What’s inside the data?

Both tools record more than just chat messages. Here’s a side-by-side comparison:

What’s storedClaude CodeCursor
User promptsIn session JSONLAcross transcripts, store.db, composerData
AI responsesIn session JSONLAcross transcripts, store.db, bubbleId blobs
Tool callsIn session JSONL (structured)In bubble payloads (toolFormerData)
Token countsEvery response, exactSome bubbles (inputTokens/outputTokens), but coverage is uneven
Thinking tracesFull extended thinking blocks (2,130 in my data)thinkingDurationMs on some bubbles
File contextImplicit via Read/Edit tool callsExplicit relevantFiles, recentlyViewedFiles fields
Sub-agentsSeparate JSONL files per sub-agentNo equivalent (Cursor subagents are server-side)
ScreenshotsBase64 PNG inline (343 in my data)Image references in some bubbles
Cache metricsExact per-response (cache read/create tokens)Not exposed locally

The cost visibility gap

Claude Code logs exact token counts on every response. Aggregate them and you get real numbers:

MetricValue
Cache read tokens3.25 billion
Cache hit rate97.8%
API-equivalent cost~$7,900
Saved by caching~$42,300

Cursor logs token counts on some bubbles, but coverage is inconsistent. Any aggregate cost estimate is a lower bound, not a full picture.


File recovery

Claude Code

Before every edit, Claude Code saves a snapshot to ~/.claude/file-history/:

file-history/<session-uuid>/
├── 12e0d72e037caf5f@v1    # before first edit
├── 12e0d72e037caf5f@v2    # before second edit
├── 12e0d72e037caf5f@v3    # before third edit

36 MB of versioned file snapshots on my machine. Plus the built-in /rewind command.

Cursor

File recovery is split across three systems:

  1. Agent checkpoints — diffs and metadata in ~/Library/Application Support/Cursor/User/globalStorage/anysphere.cursor-commits/checkpoints/
  2. VS Code local history — in ~/Library/Application Support/Cursor/User/History/ (5,162 files on my machine)
  3. Git — standard version control

Cursor checkpoints are real and useful, but they’re keyed by request ID, not session ID, so you need to cross-reference to find the right one.


Prompt history

Claude Code

~/.claude/history.jsonl — a global index of every prompt across all projects:

{
  "display": "Fix the authentication bug in login.ts",
  "timestamp": 1772598497513,
  "project": "/Users/you/Code/myapp",
  "sessionId": "f79f8cf8-..."
}

1,642 entries on my machine. Timestamped, project-tagged, session-linked.

Cursor

~/.cursor/prompt_history.json — 500 plain strings. No timestamps, no project association, no session links. A rolling buffer, not a structured log.


Data retention

Claude Code has a default 30-day TTL. Old sessions get cleaned up automatically. You can see this clearly if you check file dates.

Cursor shows no evidence of automatic cleanup. I found store.db files older than 30 days (61 of them), and local history entries going back months. It appears to keep everything indefinitely.


The AI attribution database (Cursor only)

This was the most surprising Cursor-specific finding. At ~/.cursor/ai-tracking/ai-code-tracking.db, Cursor maintains a dedicated database for tracking AI-generated code:

  • 42,000 hash entries linking code to sources (cli, composer)
  • 1,071 scored commits with fields like tabLinesAdded, composerLinesAdded, humanLinesAdded, v2AiPercentage

Cursor is tracking, at the commit level, how much of your code was written by AI vs. by you. Claude Code has no equivalent.


Context compaction

Both tools hit context window limits and need to manage them.

Claude Code handles this transparently: when the context fills up, it compresses the conversation and continues. Every compaction event is logged in the session JSONL with metadata (trigger, pre-compaction token count). I found 51 compaction events across my sessions.

Cursor manages context server-side. Local artifacts don’t expose compaction events in the same way.


The architectural takeaway

Claude CodeCursor
PhilosophyOne format, one locationMultiple systems, layered
Session formatPlain-text JSONLSQLite + JSONL + KV blobs
Inspectabilitycat and jqNeed SQLite tools + custom parsing
Session ID modelOne ID per sessionMultiple overlapping ID spaces
Total local footprint~858 MB~7 GB
Data retention30-day TTLAppears indefinite
Cost visibilityCompletePartial

Neither approach is objectively “better.” Claude Code’s simplicity makes it trivially inspectable — any developer can jq their way through a session file. Cursor’s complexity reflects a different architecture: an IDE that needs to track editor state, checkpoints, file history, and AI attribution all at once.

But if you’re trying to understand what your AI coding tool actually did — what it tried, what it cost, where it struggled — the data accessibility gap is real.


One tool that reads both

This is why I built vibe-replay.

npx vibe-replay

One command. It discovers both Claude Code and Cursor sessions, merges their respective storage formats, and generates an interactive replay you can open in any browser.

For Claude Code, it reads the JSONL directly. For Cursor, it merges the JSONL transcripts, SQLite chat databases, and global state blobs into a unified session view.

No server, no account, no data leaves your machine. The output is a self-contained HTML file you can share with your team or publish to the cloud.

Your AI coding tools store everything. Now you can actually see it.

Try it on your sessions · Watch a live demo · Explore public replays