Memory file duplication causes excessive token consumption
Status Fixed / completed
Reported on v2.1.150
Maintainer reply None cached
Workaround ✓ Mentioned in description ↑
Activity 3 comments · opened May 25, 2026 · closed May 26, 2026
Bug: Memory file duplication causes excessive token consumption
Version: 2.1.150
OS: Debian (Kali Linux)
Problem
Large CLAUDE.md and memory files with duplicate content cause:
- Context fills to 64%+ immediately on session start
- Autocompact triggers frequently
- After compaction, same duplicate content reloads
- Tokens consumed on each compact/reload cycle
Observed behavior
~/.claude/CLAUDE.md(global) contained project-specific content (41K chars)MEMORY.mdduplicated state already in project'sKZP.md/doctorflagged files but no automatic deduplication- Session used 127K/200K tokens (64%) with minimal actual work
Expected behavior
- Warning when global CLAUDE.md contains project-specific content
- Memory index should not duplicate imported CLAUDE.md content
- Autocompact should detect and skip duplicate content
Workaround
Manually trimmed:
- Global CLAUDE.md to 1K (user prefs only)
- MEMORY.md to index-only (no state duplication)
- Removed redundant @imports
Token impact
~30K tokens wasted per session on duplicate content loading
3 Comments
This is a real problem that compounds over time — the more projects you work on, the more your global CLAUDE.md accumulates project-specific cruft, and each new session pays the token tax.
A few patterns that have worked for me:
~/.claude/CLAUDE.mdto truly global preferences only (language, style, tool prefs) — anything project-specific goes in the project'sCLAUDE.md~/.claude/rules/*.mdfor cross-cutting rules that apply to multiple projects but aren't universal — they get loaded per-project, avoiding the global bloatOn the tooling side: the
@importdirectives in CLAUDE.md compound this issue because they're not deduplicated across nested files. If you have@RTK.mdand@CLAUDE.mdboth importing the same sub-file, you pay double. I've been using Mantra to review my past session context sizes and spot which files are contributing the most tokens — it helps identify exact duplicates before they eat your context budget.The 30K wasted tokens you measured is significant — that's roughly ~$0.15-0.45 per session depending on model, adding up fast for daily users.
Solution: Memory File Duplication Fix for Claude Code (Issue #62325)
Issue: https://github.com/anthropics/claude-code/issues/62325
Labels: bug, platform:linux, area:core, memory
Severity: High — ~30K tokens wasted per session, context fills to 64%+ on startup
---
1. Root Cause Analysis
1.1 Problem Summary
Claude Code loads memory from multiple sources at session start:
| Source | Path | Scope |
|--------|------|-------|
| Global CLAUDE.md |
~/.claude/CLAUDE.md| All projects || Project CLAUDE.md |
<project>/.claude/CLAUDE.md| Per-project || Rules |
~/.claude/rules/*.md| Global rules || Project Rules |
<project>/.claude/rules/*.md| Project rules || Auto-memory |
~/.claude/projects/<slug>/memory/*.md| Per-project memories || MEMORY.md / KZP.md | Project root | Project knowledge index |
The duplication occurs through four distinct mechanisms:
1.2 Mechanism 1: Global/Project Scope Overlap
Root Cause: The recursive memory loader walks from the current working directory up to the filesystem root, collecting all
CLAUDE.mdandrules/files. When~/.claude/CLAUDE.md(global) contains project-specific content, and the project also has its own.claude/CLAUDE.md, both are injected. The global file is loaded once as "User memory" and again as "Project memory" because the recursive search discovers~/.claude/as a parent directory of the workspace when the workspace is under$HOME.Evidence (Issue #19516):
~/Projects/→~/.claude/is discovered both as the User memory source AND as a parent-directory Project memory source/contextoutput with different Type labels1.3 Mechanism 2: Symlink / Git Worktree Resolution
Root Cause: When using git worktrees with symlinks, the memory loader resolves paths independently without checking for content equivalence. A single rule file accessible via two symlink paths is injected twice.
Evidence (Issue #55988):
1.4 Mechanism 3: Memory Index Content Duplication
Root Cause: The
MEMORY.md(orKZP.md) index file stores both a structured index AND duplicated state content. When the same information exists in both the index and the referenced files, the full content is loaded twice — once from the index body and once from the referenced file.Evidence (Issue #62325):
MEMORY.mdduplicated state already in project'sKZP.mdCLAUDE.mdwas 41K chars of project-specific content that duplicated project-level rules1.5 Mechanism 4: LLM-Generated Memory Fragmentation
Root Cause: The LLM sometimes creates new memory entries instead of consulting and updating existing ones. This is exacerbated when the project slug function normalizes paths (replacing
_with-) but the LLM'sWritetool calls use raw paths, creating duplicate project directories.Evidence (Issue #39424, #57786):
feedback_nao_usar_idempotente.mdinstead of consulting existingfeedback_vocabulario_tecnico.md1.6 Token Impact Calculation
---
2. Fix Approach
2.1 Strategy Overview
Implement a three-layer deduplication pipeline that operates at different stages of the memory loading lifecycle:
2.2 Fix 1: Canonical Path Deduplication (Stage 1 → Stage 2)
Resolve all paths to their canonical (real) paths before loading, then deduplicate.
2.3 Fix 2: Content-Hash Deduplication (Stage 2)
For cases where canonical path dedup is insufficient (e.g., intentionally different worktree overrides), deduplicate by content hash.
2.4 Fix 3: Memory Index vs Entry Deduplication (Stage 2)
Prevent MEMORY.md/KZP.md index files from duplicating content that exists in referenced entries.
2.5 Fix 4: Global vs Project Scope Separation
Warn and auto-trim when global CLAUDE.md contains project-specific content.
2.6 Fix 5: PreMemoryLoad Hook Surface
Allow users to implement custom deduplication logic via a hook.
2.7 Fix 6: Slug Normalization for Write Tool
Ensure the LLM's memory writes always target the canonical project directory.
---
3. Testing Strategy
3.1 Unit Tests
3.2 Integration Tests
3.3 Regression Tests
| Scenario | Expected | Test |
|----------|----------|------|
| Workspace under
$HOME| No duplicate loading |integration.test.ts:12|| Git worktrees with symlinks | Single injection per file |
integration.test.ts:30|| Global CLAUDE.md with project content | Warning + dedup |
dedup.test.ts:67|| MEMORY.md with duplicated entries | Stripped to index-only |
dedup.test.ts:45|| Path with underscores | Single canonical directory |
project-slug.test.ts|| PreMemoryLoad hook | Transformed plan used |
hook.test.ts|3.4 Performance Benchmarks
---
4. Code Changes Summary
4.1 Files to Create
| File | Purpose |
|------|---------|
|
src/memory/dedup.ts| Core deduplication logic (canonical path + content hash) ||
src/memory/index-dedup.ts| MEMORY.md/KZP.md index deduplication ||
src/memory/global-scope-check.ts| Global vs project scope separation + warnings ||
src/hooks/pre-memory-load.ts| PreMemoryLoad hook surface ||
src/memory/project-slug.ts| Canonical slug + Write tool path canonicalization ||
tests/memory/dedup.test.ts| Unit tests for deduplication ||
tests/memory/integration.test.ts| Integration tests ||
tests/memory/benchmarks.test.ts| Performance benchmarks ||
tests/memory/project-slug.test.ts| Slug normalization tests ||
tests/memory/hook.test.ts| PreMemoryLoad hook tests |4.2 Files to Modify
| File | Change |
|------|--------|
|
src/memory/loader.ts| Integrate dedup pipeline into memory loading flow ||
src/memory/context-builder.ts| Add token savings reporting to/contextoutput ||
src/commands/doctor.ts| Add auto-detection + auto-fix for duplicate memory content ||
src/config/settings.ts| Addmemory.deduplication.enabledsetting (default: true) ||
src/config/settings.ts| Addmemory.preMemoryLoadHooksetting for custom hooks ||
src/tools/write.ts| IntegratecanonicalizeMemoryWritePath()for memory writes ||
src/session/start.ts| Emit global content warnings at session start |4.3 Configuration Schema Addition
4.4 Integration Points
---
5. Expected Impact
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| Tokens at session start | 127K/200K (64%) | ~40K/200K (20%) | -69% |
| Duplicate content per session | ~30K tokens | ~0 tokens | -100% |
| Autocompact frequency | Every 3-5 turns | Every 15-20 turns | 4x fewer |
| Annual token cost (daily sessions) | ~$1,100 | ~$350 | ~$750 saved |
| Silent override risk | Present | Eliminated | N/A |
---
6. Migration Notes
/memory-reportcommand shows deduplication statisticsThis issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.