History accumulation in .claude.json causes performance issues and storage bloat

Open 💬 53 comments Opened Aug 3, 2025 by ravikalla

Description

The .claude.json file continuously accumulates conversation history for each project, leading to:

  • File sizes growing to hundreds of MB or more
  • Slower Claude Code startup times
  • Potential system performance degradation
  • No automatic cleanup mechanism

Current Behavior

  • Every conversation in every project is stored indefinitely
  • History entries include full conversation context, pasted contents, and metadata
  • File can grow to 968KB+ (as observed) and continues growing
  • No built-in limits or rotation mechanism

Expected Behavior

  • Automatic history rotation/cleanup after reaching a size limit
  • Configurable history retention (e.g., last N conversations or last X days)
  • Option to disable history storage entirely
  • Better separation of configuration (MCP servers) from history data

Impact

  • Users must manually edit .claude.json to remove old history
  • Risk of losing MCP server configurations during manual cleanup
  • Performance degradation as file size increases
  • Poor user experience for long-term users

Suggested Solutions

  1. Implement automatic history rotation (e.g., keep only last 100 conversations per project)
  2. Add configuration option for history retention limits
  3. Separate history storage from configuration storage
  4. Add claude history prune command with options like --older-than 30d
  5. Show warnings when history file exceeds certain size thresholds

Environment

  • Claude Code version: Latest
  • OS: macOS (but affects all platforms)
  • File size observed: 968KB+ and growing

Reproduction Steps

  1. Use Claude Code regularly across multiple projects
  2. Check ~/.claude.json file size after a few weeks/months
  3. Observe performance degradation and file bloat

Workaround

Currently users must manually edit .claude.json or use claude history clear which removes ALL history across all projects.

View original on GitHub ↗

53 Comments

github-actions[bot] · 11 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/1449
  2. https://github.com/anthropics/claude-code/issues/2539
  3. https://github.com/anthropics/claude-code/issues/2713

If your issue is a duplicate, please close it and 👍 the existing issue instead.

🤖 Generated with Claude Code

aretrace · 11 months ago

claude history clear
@ravikalla I'm unfamiliar with this cli command

bStyler · 11 months ago

Experiencing the same issue.

colonelpanic8 · 11 months ago

@bcherny mentioned that this was being worked on a while ago (May 30th) https://github.com/anthropics/claude-code/issues/1449#issuecomment-2923686711

are there any updates on this work?

jezweb · 11 months ago

do i just rename the file and move on? the file is 90mb and i cant even open it to edit the file

sukakcoding · 11 months ago

+1

jezweb · 11 months ago

If I run this command
claude history clear
is that going to remove all the conversational history of every project?

auggie246 · 11 months ago

claude history clear works for most part but pasted contents are somehow populated in ~/.claude.json too.
Honestly, too much junk in this file.

tesciarz · 10 months ago

Message history shouldn't be in the configuration file. It's pointless. This file is getting huge and causes problems with mcp. Do you plan to fix this bug?

mattdowney · 10 months ago

Experiencing the same problem here. My conversation history is being automatically written to the projects[].history arrays in the global config file, even after manual removal.

Jahonny · 10 months ago

claude history clear didn't work for me. It opens Claude Code and it begins looking for my command history.

yachal-upson · 10 months ago

Here to +1. Was new to me. Surprised to find when checking MCP config. What a mess.
Also really don't like the config being stored down in the windows user directory but understand has to go somewhere predictable.

gebeer · 10 months ago

history should be separate from settings.

gebeer · 10 months ago
Here to +1. Was new to me. Surprised to find when checking MCP config. What a mess. Also really don't like the config being stored down in the windows user directory but understand has to go somewhere predictable.

yes. config is a mess currently. local config in .mcp.json. I'd expect user scope MCP config to be in /{user_dir}/.claude/.mcp.json.

Clean separation of concerns for config should be high priority. see https://github.com/anthropics/claude-code/issues/3098

hisnameisjoel · 10 months ago

Didn't realize how massive this file was until recently. Hitting /resume seemed to take a long time too. Now I know why. Absolutely insane for something to get this big and uncontrolled with no trimming or archiving...

hyperb1iss · 10 months ago

Yeah my .claude.json is 122MB!! Claude is slowly taking over my system lol

Here's a cleanup tool: https://gist.github.com/hyperb1iss/c2029f9c3393f8c1197267873037632c

ravikalla · 10 months ago
Found 3 possible duplicate issues: 1. Bug: .claude.json automatically stores conversation history when it shouldn't #1449 2. Unify MCP configuration and separate from conversation history #2539 3. Claude Code logs partial keystrokes and stores plaintext emails in ~/.claude.json #2713 If your issue is a duplicate, please close it and 👍 the existing issue instead. 🤖 Generated with Claude Code

This is NOT a duplicate issue. While related, it has a distinct focus:

  • #1449: Focuses on the unintended behavior of storing history in a config file
  • #2539: Focuses on separating MCP configuration from history for better organization
  • #2713: Focuses on privacy/security concerns with sensitive data storage
  • Current one #5024: Focuses on performance degradation and storage bloat from unbounded history growth
RorzGonzalez · 10 months ago

+1

NirAyalon1 · 10 months ago

+1

paradimes · 10 months ago

+1 . great suggestions!

AbewAbew · 10 months ago

why is this still an issue. having a separate mcp configuration is a no brainer

gebeer · 10 months ago
why is this still an issue. having a separate mcp configuration is a no brainer

yes, especially since on the project level it has been separated out to .mcp.json already. So why not just have one in ~/.claude for user level MCPs.

aleksadvaisly · 10 months ago

Strange design, looks like designed and written by Claude Code itself, without any reflection. Even mid developer wouldn't pickup such design decision. Anyway, it should be encrypted (once separated from configuration), otherwise it is security hole. I would rather store that in local vector db for embedding search and so on.

senseihaiku · 9 months ago

+1

atkinson · 9 months ago

prompt history and configuration are separate concerns.

yhkdev · 9 months ago
claude history clear @ravikalla I'm unfamiliar with this cli command

I have the same question. Running this command in terminal or in claude code doesn't work.

peterchabs · 9 months ago
> claude history clear @ravikalla I'm unfamiliar with this cli command I have the same question. Running this command in terminal or in claude code doesn't work.

This resolves the issue on the latest Claude Code for VS Code release 2.0.3

Workaround to temporarily fix:

Back up and remove the project directory

mv ~/.claude/projects/[your-project] ~/.claude/projects/[your-project].backup

Restart VS Code - extension will work again with fresh project

atkinson · 9 months ago
> > claude history clear @ravikalla I'm unfamiliar with this cli command > > > I have the same question. Running this command in terminal or in claude code doesn't work. This resolves the issue on the latest Claude Code for VS Code release 2.0.3 Workaround to temporarily fix: # Back up and remove the project directory mv ~/.claude/projects/[your-project] ~/.claude/projects/[your-project].backup # Restart VS Code - extension will work again with fresh project

The config is in the same fuile (allowed tools, MCP servers etc).

anikwai · 9 months ago

I have to mv .claude.json .claude.json.backup and re-aunthenticate claude again to create a new .claude.json file.

nizarzitouni · 9 months ago

+1, i just did manual clean up of 5K+ .claude.json file, if they want to save the conv why don't they save it in the actual project folder separated from the global one

thenickb · 9 months ago

This is becoming a real problem for me. I am running multiple instances of CC including multiple subagents. I'm getting corrupted file after corrupted file. I would love some progress here.

truemetal74 · 8 months ago

Please fix it! Since claude stores pasted screenshots as base64 strings as a part of the command history - the .claude.json becomes over 50MB in size and periodically gets corrupted!

nGrave · 8 months ago

+1 to this issue it makes the extension pretty much unusable most user will simply give up when it doesn't work a few times, with no feedback to the user, how about a quick fix to error out and tell the user that their file is corrupted and to clear the history until the deeper issues can be resolved

jans9000 · 8 months ago

+1 claude history clear does not work for me

mjherich · 8 months ago

Check this out: https://github.com/gagarinyury/claude-config-editor
Reddit thread: https://old.reddit.com/r/ClaudeAI/comments/1oi6347/i_built_a_gui_to_clean_up_your_bloated_claudejson/

Just found this tool for visualizing .claude.json and doing project level history exports. Was super helpful for me to export histories I wanted to keep before clearing everything. This file was 71MB on my machine! The tool also shows which MCP servers are configured there.

sam1am · 8 months ago

Switching this to a sqlite database should fix performance issues.

gebeer · 8 months ago
Check this out: https://github.com/gagarinyury/claude-config-editor Reddit thread: https://old.reddit.com/r/ClaudeAI/comments/1oi6347/i_built_a_gui_to_clean_up_your_bloated_claudejson/ Just found this tool for visualizing .claude.json and doing project level history exports. Was super helpful for me to export histories I wanted to keep before clearing everything. This file was 71MB on my machine! The tool also shows which MCP servers are configured there.

Thank you for this proactive approach to the problem. Works for me until they fix this.

maikunari · 8 months ago

I hit this issue at 79MB (17,797 lines). File was so large it was hard to debug other config issues.

Quick fix that worked for me:

# Backup first!
cp ~/.claude.json ~/.claude-backup-$(date +%Y%m%d).json

# Clean history while preserving MCP configs and project settings
jq '.projects |= (. | to_entries | map(.value |= (.history = [] | .exampleFiles = [])) | from_entries)' \
  ~/.claude.json > ~/.claude.json.clean && \
  mv ~/.claude.json.clean ~/.claude.json

Result: 79MB → 64KB (625x reduction). Much easier to work with.

Root cause: 39 projects × 100 prompts per project + large pasted content accumulating in pastedContents field.

Suggestion: Add auto-cleanup or configurable limit like history.maxEntriesPerProject: 30 (instead of 100) to prevent this from recurring.

apankov1 · 7 months ago

Ran into the same issue, luckily, Claude Code found the solution itself and found this bug.

+1

sam1am · 7 months ago
Ran into the same issue, luckily, Claude Code found the solution itself and found this bug. +1

That's got to be a first for software bugs. "The software has a bug, but the software found it and fixed itself."

dialupdisaster · 6 months ago

Since there is now a ~/.claude/sessions.db and there's BEEN a projects folder with all the projects I don't understand why we're duplicating data so much and at a huge performance and user experience impact.

okke-formsma · 6 months ago

Can this please be fixed? Multiple claude code sessions running in parallel on my mac is breaking constantly. This causes claude to forget permissions and mcp server configurations. :(

github-actions[bot] · 5 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

kolkov · 5 months ago

It hasn't been fully decided yet, as far as I can see.

aleksadvaisly · 5 months ago

guys, lets drop that json nonsense, migrate to sqlite where you add vectorisation column for embedding, allow for schema extension (like own status, markers, ref keys and so on). and close the story - everyone will be happy.

apankov1 · 5 months ago
> Ran into the same issue, luckily, Claude Code found the solution itself and found this bug. > +1 That's got to be a first for software bugs. "The software has a bug, but the software found it and fixed itself."

it did run web search and arrived here if i remember correctly. it's been a while though. I know I didn't find it myself

ichewm · 4 months ago

Has this issue reached a final conclusion?

From a personal and admittedly limited perspective, project-level records and configuration should belong to and travel with the project itself, rather than being stored globally.😂

yurukusa · 3 months ago

/tmp/issue-5024-answer.md

kolkov · 3 months ago

Update (2026-03-27): We audited the current storage architecture on a real machine (28 projects, daily use since Aug 2025). The .claude.json bloat from this issue has been partially addressed — history moved out — but the underlying problems got worse.

Current storage layout: ~/.claude/ (3+ GB, no management)

~/.claude/                              # TOTAL: ~3.1 GB on our machine
├── .claude.json                        #    87 KB — settings, per-project metrics (28 projects)
├── history.jsonl                       #    10 MB — GLOBAL prompt history (37,223 entries)
│                                       #            used for ghost-text suggestions
│                                       #            ⚠️ ALL projects, ALL sessions write here
│                                       #            ⚠️ NO file locking!
├── projects/                           #   2.5 GB — session JSONL files
│   ├── {project-path}/
│   │   ├── {uuid}.jsonl               #   up to 203 MB per session!
│   │   ├── {uuid}/subagents/          #   subagent sessions (up to 72 MB each)
│   │   │   └── agent-{name}-{hash}.jsonl
│   │   └── sessions-index.json        #   4-8 KB index ⚠️ shared, no locking
│   └── ... (28 directories)
├── file-history/                       #   232 MB — file snapshots for undo
│                                       #            ⚠️ no deduplication, no TTL
├── debug/                              #   303 MB — debug logs
│                                       #            ⚠️ never cleaned up
├── shell-snapshots/                    #     9 MB — shell state
├── tasks/                              #   883 KB — background tasks
├── plans/                              #   120 KB
├── telemetry/                          #   188 KB
├── cache/                              #   180 KB
├── stats-cache.json                    #    14 KB
├── settings.json                       #     4 KB
├── mcp.json                            #     < 1 KB
├── .credentials.json                   #     < 1 KB
└── .update.lock                        #     5 bytes (the ONLY lock file!)

Key numbers:

  • Total: 3.1 GB — no rotation, no compression, no cleanup
  • Largest single session JSONL: 203 MB (coregex project)
  • Largest subagent JSONL: 72 MB (one subagent in naga)
  • history.jsonl: 10 MB, 37K entries — every prompt from every project/session, one global file
  • file-history/: 232 MB — file snapshots with no deduplication (same file edited 10 times = 10 full copies)
  • debug/: 303 MB — never cleaned

The concurrency disaster: no locking, no transactions, no coordination

The .update.lock (5 bytes) is the only lock file in the entire ~/.claude/ directory. Everything else is unprotected.

When multiple Claude Code processes run simultaneously (which is the normal use case for agents + subagents), they all write to shared files with no coordination:

| Shared file | Writers | Protection | Known issues |
|-------------|---------|------------|--------------|
| history.jsonl | Every process, every project | proper-lockfile (stale 10s, 3 retries) | Lock exists since v2.1.85 |
| sessions-index.json | Every session in a project | None found | Race on read-modify-write |
| {uuid}.jsonl | Main session + compaction | None — raw appendFile | #31328: dropped entries |
| .claude.json | Every process | None found — raw writeFile | #28922: reported 8 times since Jun 2025 |
| file-history/* | Every Edit/Write tool call | None found | Unbounded growth |
| OAuth credentials | Token refresh | proper-lockfile | Fixed in v2.1.81 |
| Tasks | Background tasks | proper-lockfile | Protected |

Note: This analysis is based on reverse-engineering minified cli.js v2.1.85. We may have missed locking in code paths we haven't traced. However, the community-reported corruption issues (#28922, #29342, #31328) align with what we see: session JSONL and .claude.json have no locking, while history.jsonl and OAuth do.

Documented corruption from community:

  • #29342 — session writes to WRONG JSONL file (cross-session contamination)
  • #26964 — events from one session appear in another's file
  • #20992 — stack overflow from corrupted JSONL during concurrent sessions
  • #28922.claude.json race condition — reported 8 times since June 2025, all closed without fix
  • #28847.claude.json corruption with parallel instances
  • #22365 — large JSONL files hang Claude Code, consume all RAM
  • #31328 — JSONL writer drops assistant entries during parallel tool calls

Windows is worse: The atomic-write workaround (write to .tmp, then rename()) fails on Windows because rename() returns EPERM when the target file is held by another process. This breaks atomicity completely and can leave truncated files.

The pattern: moved the problem, didn't solve it

| Era | Storage | Problem | Size |
|-----|---------|---------|------|
| 2025 | .claude.json (this issue) | Single JSON, unbounded growth, no locking | Hundreds of MB |
| 2026 | JSONL files in projects/ | Many files, unbounded growth, no locking | 2.5 GB+ |

History was extracted from .claude.json into history.jsonl and per-session JSONL files. But the fundamental architecture didn't change: flat files, no locking, no transactions, no cleanup, no compression.

What's actually needed

Our earlier proposal (#7243, Sep 2025, 👍17, closed/locked by bot) and @aleksadvaisly's suggestion (Feb 2026) are still the right answer: SQLite.

A single SQLite database per user (or per project) would solve every problem simultaneously:

  • Atomic writes — WAL mode gives concurrent readers + single writer, no corruption
  • Transactions — session writes are all-or-nothing
  • Built-in compression — BLOB storage with zlib for file-history snapshots
  • TTL cleanupDELETE FROM sessions WHERE modified < datetime('now', '-30 days')
  • Deduplication — hash file contents, store once, reference many times
  • No more 203 MB flat files — proper indexing, instant queries
  • Cross-platform — same behavior on Windows, Linux, macOS

Alternatively, a local daemon/service (one per user) that all Claude Code processes communicate with via IPC would provide coordination without changing the storage backend. This is how LSP servers, Docker, and other multi-process tools solve the same problem.

The current approach — dozens of processes writing to flat files with zero coordination on a single-threaded JS runtime that can't even guarantee setTimeout fires during for await — is not an architecture. It's an accident that mostly works until it doesn't.

Related issues

  • #33949 — streaming hang root cause (our analysis, 👍12)
  • #39755 — watchdog fallback is dead code (found today)
  • #7243 — our original .claude.json issue (👍17, closed/locked by bot)
  • #23095 — .node native addon leak
  • #24207 — no disk space management
  • #31328 — JSONL writer drops entries
  • #28922 — .claude.json race condition (8 reports, all closed)
  • #29342 — cross-session JSONL contamination
  • #20992 — stack overflow from corrupted JSONL
gebeer · 3 months ago

Thank you for the thorough analysis. That should have been done by the maintainers long time ago. Let's hope they'll at least take a look at this with human eyes. All hope is not lost...

kolkov · 3 months ago

@ichewm No, far from it. They moved history out of .claude.json into per-session JSONL files under ~/.claude/projects/, but the result is actually worse — see our audit above. 3.1 GB with no cleanup, no rotation, session files up to 203 MB each.

Your point about project-level storage is spot on. Right now it's organized into per-project directories, but they're all under ~/.claude/projects/ — not inside the actual project. So when you move or clone a project to another machine, all Claude Code context (sessions, permissions, memory) stays behind. It's global storage with project-flavored folder names, not true project-local storage.

kolkov · 3 months ago

@gebeer Thanks. Unfortunately, in our experience tracking these issues since August 2025 — across #33949 (👍12, 21 comments), #35171, #36132, #7243 (closed/locked by bot), and now this — we've never seen an Anthropic team member respond with "we understand the problem and will fix it." It's either silence, or generic "we're actively investigating" followed by months of nothing. @catherinewu posted "actively investigating" on a related issue — 30+ days of silence after.

The irony is that the community is literally doing their debugging for them — reverse-engineering minified code, tracing error paths, proposing fixes with code snippets — and the response is a stale-issue bot that closes everything after 60 days.

Whether they actually read these — open question. Every release has a long list of new features, but the core workflow bugs — streaming hangs, data corruption, unbounded storage growth — remain unfixed for months. And when something does get addressed, it tends to be a quick patch rather than a thoughtful architectural fix. Case in point: .claude.json bloat → moved to JSONL files → same unbounded growth, same lack of locking, now spread across 2.5 GB of files instead of one.

But we keep documenting anyway, because when someone finally looks, the analysis will be here waiting.

urav06 · 3 months ago

Built a plugin with a prune command for this: github.com/urav06/claudestrophobic

/sessions prune --older 2w shows sessions older than 2 weeks and deletes on confirm. It cleans up transcripts, subagent data, file-history, and session-env directories per session. Cleanup paths are based on Claude Code's recently surfaced internals. Doesn't address the .claude.json rotation issue discussed here, but helps keep the session side under control.