Claude Code Memory System Guide: CLAUDE.md, Auto Memory, and Rules in Practice
Every time you open Claude Code, it acts like it has amnesia. The code style you agreed on, the project architecture, even the bugs you corrected last session — all gone. This isn't a bug. It's by design. Each Claude Code session starts with a fresh context window.
But Claude Code does have memory. Three kinds, actually. Once I figured out how they work, my productivity with Claude Code roughly doubled. No more re-explaining the project structure every session, no more correcting the same mistakes.
Let me walk through each memory mechanism and what I've learned using them day to day.
The Two Core Memory Systems
Claude Code has two complementary memory systems, both loaded at the start of every conversation:
- CLAUDE.md files — instructions you write to give Claude persistent context
- Auto Memory — notes Claude writes itself based on what it learns
One is something you actively feed it. The other it accumulates on its own. Get both right, and Claude Code goes from "new intern every session" to "developer who already knows the codebase."
CLAUDE.md: Your Project Manual for Claude
A CLAUDE.md is just a Markdown file that Claude reads at the start of every session. Think of it as an onboarding document for a new teammate — except this teammate loses their memory every time.
When to add to CLAUDE.md
Not everything belongs here. The official guidance is simple:
- Claude made the same mistake twice
- A code review caught something Claude should have known
- You typed the same correction you typed last session
- A new teammate would need the same context
In other words: stuff you're tired of repeating.
Where to put CLAUDE.md files
This is where it gets confusing. CLAUDE.md can live in several locations, each with different scope:
User level — ~/.claude/CLAUDE.md
Your personal preferences that apply to all projects. "I prefer pnpm over npm." "Use 2-space indentation."
Project level — ./CLAUDE.md or ./.claude/CLAUDE.md
Team-shared project conventions. Committed to git, visible to everyone. "Build with pnpm build." "Tests use vitest."
Local level — ./CLAUDE.local.md
Your personal preferences for this specific project. Not committed to git. "My local DB password is xxx." "I like running unit tests before committing." Add it to .gitignore.
Directory level — CLAUDE.md in subdirectories Only loaded when Claude reads files in that subdirectory. Good for module-specific rules in large projects.
The loading order walks up from the filesystem root to your current directory, so project-level instructions override user-level ones.
How to write effective CLAUDE.md files
The biggest mistake I made was writing a CLAUDE.md that was too long. Claude stopped following it — too much content, and it couldn't focus on what mattered.
A few things I learned the hard way:
Keep it under 200 lines. CLAUDE.md consumes context window tokens. Longer files actually reduce compliance. If you have a lot of content, split it into .claude/rules/ with path-scoped loading.
Be specific, not vague. "Use 2-space indentation" beats "format code properly." "API handlers live in src/api/handlers/" beats "keep files organized." The more concrete, the better Claude follows.
Avoid contradictions. If two rules conflict, Claude picks one at random. Periodically audit your CLAUDE.md and rules directory for outdated or contradictory instructions.
Use Markdown structure. Headers, lists, grouping. Claude scans structure the same way humans do — organized beats wall-of-text every time.
A practical CLAUDE.md example
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
Short and focused. Claude reads it every session and immediately knows how the project works.
Importing other files
CLAUDE.md supports @path/to/file syntax for importing:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
Imported files get loaded into context at startup alongside the CLAUDE.md that references them. Note: this doesn't reduce token usage — the full content still enters the context window. But it does keep things organized.
AGENTS.md compatibility
If your repo already uses AGENTS.md for other AI coding tools, you can import it directly:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
Or just symlink: ln -s AGENTS.md CLAUDE.md.
.claude/rules/: Path-Scoped Rules
When your project grows beyond what a single CLAUDE.md can handle, .claude/rules/ comes to the rescue. The killer feature: rules can be scoped to specific file paths, so they only load when Claude is working with matching files.
Basic setup
Create a .claude/rules/ directory with topic-specific files:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
Rules without a paths field load unconditionally at startup.
Path-specific rules
This is where it gets powerful. Use YAML frontmatter with a paths field:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
This rule only activates when Claude reads files under src/api/. Otherwise, it doesn't consume context at all.
Glob patterns supported:
**/*.ts— all TypeScript filessrc/**/*— everything under src/src/components/*.tsx— React components in a specific directorysrc/**/*.{ts,tsx}— multiple extensions
This is incredibly useful for large projects. Frontend rules only apply to frontend files. Backend rules only to backend files. No cross-contamination.
User-level rules
~/.claude/rules/ applies to every project on your machine:
| 1 | |
| 2 | |
| 3 | |
User-level rules load before project rules, so project rules take priority.
Auto Memory: What Claude Learns on Its Own
This is the feature I find most impressive. Auto memory lets Claude take notes as it works — build commands, debugging insights, architecture decisions, code style preferences, workflow habits. It doesn't save something every session. It decides whether the information would be useful in a future conversation.
Where it lives
Each project gets its own memory directory: ~/.claude/projects/<project>/memory/. The <project> path is derived from the git repo, so all worktrees and subdirectories within the same repo share one memory directory.
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
MEMORY.md is the index. The first 200 lines (or 25KB, whichever is smaller) load at session start. Topic files like debugging.md are loaded on demand when Claude needs them.
What it actually remembers
After using it for a while, I noticed Claude had picked up things like:
- "This project uses pnpm, not npm"
- "Tests use vitest, not jest"
- "The DB connection string is in .env.local"
- "That SSR hydration error happened because the component accessed window on the server"
Every new session, it carries this knowledge. Especially the debugging lessons — once it remembers a mistake, it doesn't repeat it.
Managing auto memory
Type /memory in Claude Code to see everything that's loaded — CLAUDE.md files, rules, and auto memory. You can toggle auto memory on/off, and open the memory folder to edit files directly.
Auto memory files are plain Markdown. Edit or delete them anytime. If Claude remembered something wrong, just fix it.
To manually tell Claude to remember something: "Remember that this project uses pnpm." Claude saves it to auto memory. For CLAUDE.md instead: "Add this to CLAUDE.md."
What survives /compact
Project-root CLAUDE.md survives compaction — after /compact, Claude re-reads it from disk and re-injects it. Subdirectory CLAUDE.md files don't auto-reload; they load next time Claude reads a file in that directory.
So put critical instructions in the root CLAUDE.md. Otherwise they might get "forgotten" after compaction.
Auto memory is unaffected by compaction — it lives on disk and gets re-read at session start regardless.
Practical Organization Tips
After months of use, here's the system I settled on:
CLAUDE.md holds:
- Project architecture and directory layout
- Build, test, deploy commands
- Team coding standards
- Important "always do X" rules
CLAUDE.local.md holds:
- Local dev environment config
- Personal preferences (doesn't affect team)
- Test database/service addresses
.claude/rules/ holds:
- Module-specific rules (frontend, backend, database)
- Path-specific rules (API validation, component standards)
- Special requirements for sensitive directories (billing, auth)
Auto memory:
- Let Claude accumulate it naturally
- Periodically review and remove stale entries
- Debugging lessons — let Claude record them itself, more accurate than you writing them
Common Issues
Claude isn't following CLAUDE.md
Run /memory to verify the file is loaded. If loaded but ignored, make instructions more specific. If a rule must be enforced (like "run lint before commit"), use a Hook instead — Hooks are mandatory, CLAUDE.md is advisory.
CLAUDE.md is too large
Over 200 lines and compliance drops. Split into .claude/rules/ with path scoping. Or use @import for separate files (though this doesn't reduce token usage, just organization).
Auto memory saved something wrong
Go to ~/.claude/projects/<project>/memory/ and edit or delete. All plain text, no special format.
Monorepo interference from other teams' CLAUDE.md
Use claudeMdExcludes in .claude/settings.local.json:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
Need system-prompt-level instructions
CLAUDE.md is injected as a user message, not a system prompt. For system-prompt level, use --append-system-prompt. But this needs to be passed every invocation, so it's better for scripts and automation.
Wrapping Up
Claude Code's memory system looks simple — just a few Markdown files — but the difference between using it well and ignoring it is huge. The key is finding balance: enough context for Claude to understand the project, but not so much that it gets drowned in noise.
My current setup: CLAUDE.md stays around 50 lines with core rules and build commands. Module-specific rules go in the rules directory. Auto memory stays on, and I check what Claude recorded every once in a while. Now every time I open Claude Code, it already knows 80% of the context. I just need to tell it what to do.
Planning to dig into the Hooks system next — that's the real enforcement mechanism, not relying on Claude's "judgment." Will write about that when I get to it.
Questions? Drop them in the comments.