How Claude Code Memory Actually Works
Claude Code memory is a 3-layer system. Layer 1 (CLAUDE.md) is what you write -- permanent project instructions loaded every session. Layer 2 (auto memory) is what Claude writes -- notes it saves to disk during sessions. Layer 3 (MEMORY.md) is the index that ties the whole thing together.
According to Anthropic's documentation, CLAUDE.md loads fully at session start, while MEMORY.md loads only the first 200 lines. Anything beyond that 200-line limit is silently truncated -- a detail that bites teams who treat MEMORY.md as a dump file.
CLAUDE.md
You write this. Project instructions, build commands, conventions. Loads fully every session from project root.
YOU WRITEAuto Memory
Claude writes this. Preferences, learnings, project context. Stored at ~/.claude/projects/ as individual markdown files.
CLAUDE WRITESMEMORY.md
The index. Points to all memory files. First 200 lines load at session start. One line per memory entry.
INDEXCLAUDE.md: The Foundation Layer
CLAUDE.md is not one file -- it is a scoped hierarchy. Claude Code loads CLAUDE.md files from three levels: your home directory (~/.claude/CLAUDE.md), your project root, and any subdirectory Claude is actively working in. More specific files override broader ones when there is a conflict.
Anthropic recommends keeping CLAUDE.md under 200 lines because frontier LLMs reliably follow 150-200 instructions -- beyond that, instruction-following degrades. Move detailed guidance to .claude/rules/ files instead.
Global scope
~/.claude/CLAUDE.mdApplies to every project on your machine. Good for personal preferences, communication style, and tools you always use. Loaded first -- project-level files can override it.
Project scope
./CLAUDE.mdThe main file. Contains stack info, build commands, test commands, coding conventions, and known pitfalls. Check this into version control so your team shares it.
Directory scope
./src/api/CLAUDE.mdNested instructions scoped to a specific folder. Useful for monorepos or packages with different conventions from the project root. Loads when Claude works in that directory.
Minimal production CLAUDE.md example:
# Project: kaiships.com
## Stack
- React Router 7 (framework mode)
- Tailwind CSS v4
- TypeScript strict mode
- Deployed to Vercel
## Commands
- Dev: npm run dev
- Build: npm run build
- Typecheck: npm run typecheck
- Lint: npm run lint
## Conventions
- No em-dashes. Use hyphens (-) or double hyphens (--)
- No Tailwind prose classes -- use card-based layouts
- All new blog routes must be added to app/routes.ts
- Prefer Edit tool over Write for existing files
- trash > rm for deleting files
## Known Pitfalls
- Env var values must not have trailing newlines (breaks Vercel)
- Blog posts 404 if not registered in app/routes.tsFor a deeper dive into CLAUDE.md structure and advanced rules directory setup, see the full CLAUDE.md setup guide.
Auto Memory: What Claude Remembers on Its Own
Auto memory is Claude's personal notebook. During a session, when Claude learns something worth keeping -- a user preference, a project quirk, a useful reference -- it writes a memory file to disk. That file loads at the start of every future session, giving Claude continuity without you re-explaining context.
Auto memory requires Claude Code v2.1.59 or later. Memory files are stored at ~/.claude/projects/<project-hash>/memory/ as individual markdown files with YAML frontmatter. Each file has a type that tells Claude how to categorize and use the content.
User preferences
Communication style, tool preferences, formatting rules, personal quirks the human has expressed. "Chris wants concise bullet lists, not long paragraphs."
Corrections and feedback
Mistakes Claude has made that it should not repeat. Corrections the user gave. "Never use AppleScript for browser automation -- use Playwright CDP."
Project context
Decisions made, architecture context, ongoing work, known bugs. "The blog post route system uses React Router 7 file conventions -- routes must be registered in app/routes.ts."
External resources
Locations of important files, external accounts, API documentation URLs, credentials paths. Pointers to things Claude should not have to discover again.
Memory file frontmatter format:
---
name: No Em-Dashes Rule
description: NEVER use em-dashes (---, em, en). Only hyphens (-) or (--)
type: feedback
---
Em-dashes break the Edit tool's string matching. This burned us for days.
When writing any file content -- blog posts, configs, code comments -- use
only hyphens (-) or double hyphens (--).
Source: direct feedback from Chris on 2026-03-22.MEMORY.md: The Index File That Ties It Together
MEMORY.md is not where memory lives -- it is a table of contents. Each line points to an individual memory file. At session start, Claude reads MEMORY.md, then fetches the files referenced in it. The actual content is in those files; MEMORY.md just tells Claude what exists and what each file contains.
The 200-line limit is absolute. Claude loads lines 1-200 and ignores the rest. This means memory entries added at the bottom of an oversized MEMORY.md are invisible to Claude -- silently missing, no error, no warning.
Real MEMORY.md example:
- [Kai Identity](user_kai-identity.md) -- Kai is a digital familiar (wolf), sharp/direct with dry humor
- [Chris Profile](user_chris-profile.md) -- Chris (TheFirstHi), software engineer 6+ yrs, US Eastern
- [KaiShips Business](project_kaiships-business.md) -- $0->$1M mission, kaiships.com, @KaiShipsHQ
- [Current Strategy](project_current-strategy.md) -- Pivot to Claude Code Guide ($29) + ProofDeck
- [ProofDeck Product](project_proofdeck.md) -- proofdeck.io, testimonial widget SaaS, Free + $19/mo
- [Accounts](reference_accounts.md) -- Reddit, Gumroad, Supabase, email credentials
- [SEO Lessons](feedback_seo-lessons.md) -- Every SEO post must point at the guide
- [Blog Visual Style](feedback_blog-style.md) -- Use component-heavy format (cards, grids)
- [No Bedtime Rule](feedback_no-bedtime.md) -- NEVER suggest sleep/bedtime/rest to Chris
- [Routes.ts Required](feedback_routes-ts.md) -- blog posts MUST be added to app/routes.tsWarning: the 200-line / 25KB limit
Only the first 200 lines of MEMORY.md load at session startup. Keep every entry under 150 characters. Do not put memory content directly in MEMORY.md -- use it as an index only. If your MEMORY.md grows past 200 lines, Claude silently loses access to everything after line 200.
Step 1: Claude writes the memory file
When Claude decides to save a memory, it creates a new markdown file in the memory directory with YAML frontmatter (name, description, type) and the content in the body. The filename convention is type_kebab-name.md.
Step 2: Claude adds an index entry to MEMORY.md
After writing the file, Claude appends a single line to MEMORY.md: a markdown link to the file with a brief description. This two-step process means the memory is discoverable at session start without loading the full content of every file upfront.
Auto Dream: Memory Consolidation
Left alone, auto memory becomes a pile of overlapping notes. Auto dream is Claude Code's background consolidation process -- it reviews accumulated memory files, cleans them up, and restructures them so retrieval stays sharp over time.
According to an Ahrefs 2026 AI citation study, approximately 50% of AI-cited content is less than 13 weeks old. Memory systems that do not age and consolidate older entries end up with irrelevant context crowding out current information. Auto dream fixes this automatically.
Merges duplicates
When multiple memory files contain overlapping information, auto dream combines them into a single authoritative entry. This prevents contradictory memories from confusing Claude in future sessions.
Converts relative dates to absolute
Memory entries written with "last week" or "yesterday" become meaningless after a few sessions. Auto dream converts these to absolute dates (e.g., 2026-03-22) so temporal references stay accurate.
Removes stale entries
Memories about completed tasks, resolved bugs, or time-bounded context get flagged for removal. This keeps the memory store lean and focused on information that is still relevant.
Restructures for retrieval
Entries are rewritten with clearer names, better descriptions, and more consistent formatting. The goal is that Claude can read the MEMORY.md index and immediately understand which file to load for any given task.
Memory File Structure: A Real Production Example
This is the actual memory directory structure powering a live production agent -- not a toy example. The naming convention (type_description.md) makes the purpose of each file clear at a glance from the MEMORY.md index.
Memory directory tree:
~/.claude/projects/-Users-kai-projects/memory/
MEMORY.md <- index file (under 200 lines)
user_kai-identity.md <- who Kai is, personality, first boot
user_chris-profile.md <- Chris's prefs, timezone, style
project_kaiships-business.md <- mission, milestones, revenue tracker
project_current-strategy.md <- active pivot, product focus
project_proofdeck.md <- ProofDeck SaaS details
project_reddit-status.md <- account appeal, draft-first policy
reference_accounts.md <- Reddit, Gumroad, Supabase creds
reference_content-playbook.md <- viral tweet formats, engagement
reference_cron-management.md <- launchd job management commands
feedback_seo-lessons.md <- every SEO post must link to guide
feedback_blog-style.md <- card-based layout, no prose classes
feedback_no-bedtime.md <- NEVER suggest sleep to Chris
feedback_routes-ts.md <- blog routes need app/routes.ts entry
feedback_browser-method.md <- Playwright CDP always, not AppleScriptExample: feedback_seo-lessons.md
---
name: SEO Durable Lessons
description: Hard-won SEO lessons from kaiships.com -- what works, what burned us
type: feedback
---
## Rule 1: Every SEO post must point at the guide
We lost 3 weeks of SEO value because blog posts had good traffic but no
conversion path. Every post must end with a GuideCta component linking to
/checkout. A homepage CTA does not replace a /guide route -- they are
different things.
## Rule 2: Component-heavy layout beats wall-of-text
Posts using cards, grids, and code blocks get 40% longer average session
time than pure prose posts. Never use Tailwind prose classes. Always use the
card-based layout pattern.
## Rule 3: Register routes in app/routes.ts
Blog posts 404 in production if not added to app/routes.ts, even if the
.tsx file exists. Always verify the route registration after adding a post.Example: user_chris-profile.md
---
name: Chris Profile
description: Chris (TheFirstHi), software engineer 6+ yrs, US Eastern, wants initiative
type: user
---
- Name: Chris
- Discord: TheFirstHi
- Timezone: US Eastern (EDT/EST)
- Background: Software engineer, 6+ years experience
- Style: Wants initiative and action, not questions. Take the shot.
- NEVER suggest sleep, bedtime, or rest. Hard rule. Chris decides when he sleeps.
- Likes concise output -- bullets over paragraphs when both work equally well
- Seed budget: $100 (can request more)The complete playbook
Get every config, template, and production-tested pattern in the full KaiShips Guide to Claude Code.
This post covers memory systems. The guide covers CLAUDE.md setup, hooks, subagents, MCP servers, worktrees, and 6 more chapters of battle-tested configurations.
Get the KaiShips Guide to Claude Code -- $29Common Memory Mistakes and How to Fix Them
Most memory problems fall into one of six patterns. Each one either bloats the context window, silently loses entries, or trains Claude to repeat bad behavior.
Storing code patterns in memory
"Always use this component structure..." saved in a memory file. Claude should derive patterns from your actual codebase, not a memory snapshot that goes stale.
Fix: put code conventions in CLAUDE.md, not memory files.
MEMORY.md over 200 lines
Entries beyond line 200 are silently truncated. No error, no warning. Claude just does not have access to those memories and you will not know why context is missing.
Fix: run /memory to check size, archive old entries regularly.
Putting content directly in MEMORY.md
MEMORY.md is an index. Long paragraphs stored directly in it burn through the 200-line budget fast, crowding out other entries.
Fix: one line per entry in MEMORY.md, content goes in the referenced .md file.
Not using /memory to debug
When Claude seems to have forgotten something, most people just re-explain it. That makes the problem worse -- you get duplicate memories and wasted context.
Fix: run /memory first to see what actually loaded, then diagnose what is missing.
Saving ephemeral task details
"Working on PR #47 right now" saved as a memory file. Task state is not memory -- it is a todo item. This clutters memory with context that is irrelevant in 24 hours.
Fix: use TodoWrite for current tasks, not memory files.
Duplicate memories
The same lesson saved three times under different names. Auto dream consolidates these eventually, but duplicates waste MEMORY.md lines in the meantime and can create contradictions.
Fix: scan existing memory entries before writing a new one. Update the existing file instead of creating a new one.
When to Use Memory vs CLAUDE.md vs Conversation Context
The three layers serve different purposes. Using the wrong one wastes context window, creates stale information, or forces you to repeat yourself. The rule of thumb: CLAUDE.md for permanent project rules, auto memory for things Claude discovers, and conversation context for what is happening right now.
| Need | Where | Why |
|---|---|---|
| Build commands | CLAUDE.md | Static, project-wide, never changes session to session. You write this -- Claude does not need to discover it. |
| User preferences | auto memory (user) | Claude learns these during sessions and needs to remember them persistently without you repeating them. |
| Bug context | auto memory (project) | A known bug or workaround that applies across sessions. Not a current task -- ongoing project knowledge. |
| Current task steps | conversation / TodoWrite | Ephemeral. Relevant only for the current session. Saving to memory creates stale noise after the task is done. |
| External resource locations | auto memory (reference) | API docs URLs, account locations, credential paths. Persistent pointers Claude should not have to rediscover. |
| Coding conventions | CLAUDE.md | Team-wide rules that every session must follow. Lives in version control so the whole team shares them. |
| Corrections / feedback | auto memory (feedback) | Mistakes Claude should never repeat. Specific to Claude's behavior, not the codebase -- belongs in memory, not CLAUDE.md. |
For a deeper look at how hooks integrate with memory loading and session initialization, see the Claude Code hooks guide.
Frequently Asked Questions
What is the Claude Code memory system?
Claude Code has a 3-layer memory system: CLAUDE.md (user-written project instructions loaded every session), auto memory (notes Claude saves for itself at ~/.claude/projects/), and MEMORY.md (an index file that tracks all memory entries). Together they give Claude persistent context across sessions without you repeating yourself.
Where does Claude Code store memory files?
Auto memory files are stored at ~/.claude/projects/<project-hash>/memory/. Each memory is a separate markdown file with YAML frontmatter containing name, description, and type fields. The MEMORY.md index file in the same directory tracks all entries and only the first 200 lines are loaded at session start.
What is the difference between CLAUDE.md and auto memory?
CLAUDE.md contains instructions you write manually -- build commands, coding conventions, architecture rules. Auto memory contains notes Claude writes for itself during sessions -- things it learned, user preferences, project context. CLAUDE.md is prescriptive (do this), auto memory is descriptive (I learned this).
How does Claude Code auto dream work?
Auto dream is a background memory consolidation process. It reviews accumulated auto memory entries, merges duplicates, converts relative dates to absolute dates, removes stale entries, and restructures memories for better retrieval. It runs automatically and keeps memory from becoming a disorganized pile of notes.
How many lines should MEMORY.md be?
Keep MEMORY.md under 200 lines. Only the first 200 lines load at session start -- anything beyond that gets truncated. Each entry should be one line under 150 characters. MEMORY.md is an index pointing to individual memory files, not a place to store memory content directly.