TLDR; Claude Code memory is selective: a new session reloads your instruction files and some of Claude’s own notes, not yesterday’s conversation. Put project rules in CLAUDE.md, let auto-memory hold corrections and preferences, and write task decisions to a plan file so they survive compaction. Keep knowledge that transfers across projects in a separate vault, with a searchable title on every entry and a routine for checking it.
When to use Claude Code memory layers
- Claude asks again about something you settled yesterday. The decision lived only in the chat; it belongs in a file.
- You keep correcting the same behaviour. A correction saved to auto-memory carries into later sessions on the same project.
- You solve the same problem on a second project. That fix belongs in a vault, a folder of notes every project can read.
- Your CLAUDE.md keeps growing. Most of what lands there belongs in another layer.
- Skip the vault for work on a single project. CLAUDE.md, auto-memory and plan files cover it; a vault pays off once knowledge repeats across projects.
How Claude Code memory works
A new session does not restore the conversation before it. It reloads files instead. CLAUDE.md holds the instructions you write. Auto-memory holds notes Claude saves for itself, and the start of its index loads too.
Within a session, the context window (the amount of text Claude can hold at once) is working memory, and the easiest to lose. When the window fills, or you run /compact, Claude Code compacts the conversation into a summary to free space. The summary loses detail. A file on disk stays intact and can be read again after compaction or in the next session.
Which Claude Code memory layer holds which kind of knowledge:
| I want Claude to remember... | Layer | Why |
|---|---|---|
| “Always use kebab-case for routes” | CLAUDE.md | Project convention, needed every session |
| “I’m a CTO, prefer concise responses” | Auto-memory | Personal preference learned on this project |
| “Stop adding trailing summaries” | Auto-memory | Behavioural correction, persists across sessions |
| “GRDB uses WAL mode for concurrent reads” | Vault | Technical knowledge, useful across projects |
| “DataForSEO keyword_suggestions takes a string, not an array” | Vault | API gotcha, useful across client projects |
| “We decided on cursor-based pagination” | Plan file (disk) | Session decision, needs to survive compaction |
| “The three test failures we haven’t fixed” | Guided compact | Needed until the task is done; you tell /compact to keep it |
| “Deploy process for this client” | Skill | Packaged instructions, loaded only when a task needs them |
How to set up Claude Code memory
1. Keep CLAUDE.md for rules every session needs
CLAUDE.md loads at the start of every session, and in the sub-agents (helper sessions Claude starts for one job) that inherit project instructions. Each session you pay for every line again in tokens, the word fragments Claude reads. In my audit of one client project, CLAUDE.md had grown to 280 lines, roughly 8,500 tokens. That took 4.3% of a 200K window before I’d done anything. Across 15 sessions in a day, loading it came to 127,500 tokens.
- 280LinesA client project’s CLAUDE.md
- 8,500TokensRoughly, loaded before any work
- 4.3%Of a 200K windowConsumed before I’d done anything
- 127,500Tokens a dayAcross 15 sessions, CLAUDE.md loading alone
Keep what Claude can’t guess: build and test commands, conventions that differ from the defaults, traps specific to the codebase, and hard limits. Deployment steps, business background and API details feel like project instructions, but most sessions don’t need them: move them to skills. The CLAUDE.md guide covers the structure, the trimming audit and on-demand loading.
Check: removing any line would cause Claude to make a mistake, and the file is under 200 lines, the limit Anthropic recommends.
2. Let auto-memory hold corrections and preferences
As you work, Claude Code can save notes as Markdown files in a memory folder, by default one per git repository (~/.claude/projects/<project>/memory/). It adds a one-line pointer to each in a MEMORY.md index, and that line is how Claude finds the note again. It needs no effort from you: correct Claude, and the next session can follow the correction.
Plan around its limits. The official documentation describes them, and a Zilliz/Milvus analysis of the v2.1.88 source confirms them:
- Startup limit: Claude Code loads the first 200 lines or 25KB of
MEMORY.mdat startup; the memory files it points to stay available, and Claude reads one when the task calls for it - No search by meaning: Claude finds a note by reading the index and searching file text; nothing indexes notes by meaning
- One repository, one machine: by default memory is scoped to the git repository (shared across its worktrees and subdirectories). The
autoMemoryDirectorysetting can point projects at one shared folder, but nothing syncs it across machines
Check: run /memory, open the auto-memory folder, and read MEMORY.md: each line names one memory specifically enough that you’d know what it holds.
3. Write task decisions to a plan file
Early in any complex task, ask Claude to write the implementation plan to a Markdown file and to update it as you decide things. Mark up the file itself, round after round, instead of discussing changes in the chat.
After compaction, or the next day, point Claude back at the file. The session craft guide has the prompt, guided compaction and a handoff file that can replace /compact.
Check: start a new session and tell it only to read the file: it can name every decision made so far.
4. Start a vault for knowledge that crosses projects
Auto-memory stays inside one repository by default, but a debugging insight from one Rails project applies to other Rails projects too. That knowledge goes in the vault: plain Markdown files, one entry per file, synced across machines with no server or database to run. Sort entries into a few broad categories and tag them. Good tags beat a deep category tree.
The filtering rule: would this help in a different project? If yes, it goes in the vault. If no, it stays in the project’s auto-memory. “The Client X API requires auth header format Y” is project memory, useless anywhere else.
Start every entry with frontmatter (a few fields between --- lines), then the same four sections, so Claude knows where to find the answer:
---
title: SwiftUI alert bindings can't use .constant(), must use @State binding
tags: [swiftui, alerts]
confidence: high
---
## Summary
The quick answer, in a sentence or two.
## Key Findings
The detail: what works, what doesn't, and on which versions.
## Gotchas
The traps.
## Related
[[swiftui-state-bindings]]
The title matters most: it is the line Claude reads in the index before it opens an entry. Make it specific:
- Bad: “SwiftUI gotcha”, too vague to match any particular search
- Good: “SwiftUI alert bindings can’t use .constant(), must use @State binding”, which names the tool and the behaviour
Write the words you would search for six months from now.
Under Related, each [[wikilink]] names another entry, so one search can lead Claude to its neighbours.
Check: your first entry passes the filtering rule, its title names the tool and the behaviour, and a session on another project can answer a question from it.
5. Make saving and recalling a routine
The hardest part of any memory system is the moment you ask whether anything from a session is worth keeping. A hook can ask that question for you. A hook is a script Claude Code runs at a set point; a Stop hook runs when Claude finishes responding (hooks guide). Have it scan the transcript for words that suggest research or debugging happened, such as “turns out”, “figured out”, “root cause” and “workaround”. If it finds enough of them, it nudges you. Plain output from a Stop hook goes only to the debug log, so return the nudge in the JSON systemMessage field, which Claude Code shows you:
This session involved research or debugging. Consider using
/remember <topic>to save key learnings to the knowledge vault for future sessions.
Choose trigger words that match how you talk when you find a root cause, and point the nudge at however you save an entry.
Capture is only half the routine. Search the vault at the start of a task, so an entry saved six months ago gets used. Put a recall trigger in your global CLAUDE.md, the one that loads in every project, and the search becomes a habit:
## Knowledge vault
Before researching a technical question, search ~/.claude/knowledge-vault/:
read the index, then the entries that match. When we solve something that
would help in another project, offer to save it there.
Check: the nudge appears after a debugging session and stays quiet after a routine one, and the next related task turns up the entry.
6. Curate the vault as it grows
Past a few hundred entries, upkeep becomes its own job. Now and then, ask Claude for a hygiene pass: broken links, entries nothing links to, one-off tags that should merge into a shared tag, and much-read entries that have gone stale. Have it report, not edit; you decide what changes.
No entry count tells you when to add semantic search (search by meaning). Whether it pays for its overhead depends on entry size, how vague your searches are, how often entries change, and how well you maintain an index by hand.
Check: the latest pass finds no broken links, and you have decided what to do with every orphan it lists.
Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
| Claude suggests a convention you rejected yesterday | The decision lived only in the chat | Project convention: CLAUDE.md. Task decision: a plan file |
| A saved memory never comes back | A vague index line, or one past the first 200 lines (or 25KB) of MEMORY.md |
Rewrite the index line in the words you’d search for; keep the index short |
| Claude repeats a mistake it was corrected on | Memory records a lesson; it doesn’t enforce it | Promote the lesson to a tested hook rule (hook rules guide) |
| Vault entries are saved but never read | Nothing prompts a search at the start of a task | Add a recall trigger to your global CLAUDE.md |
| CLAUDE.md keeps growing | Situational knowledge stored as standing rules | Move procedures to skills (CLAUDE.md guide) |
In practice
I learned this on a client’s Rails API. I spent forty minutes one morning establishing naming conventions and walking Claude through how the app models the business. That afternoon, a new session suggested a naming convention we’d rejected that morning. Forty minutes of context, gone.
Auto-memory now handles the small corrections. When I told Claude to stop adding trailing summaries to every response, it saved that as a feedback memory and stopped doing it in future sessions. When I corrected a collection naming issue in 11ty, the tool that builds this site, Claude remembered the fix next time.
For knowledge that crosses projects, I built memory-vault, a private plugin that adds commands, a hook and an agent to Claude Code. The storage is a folder at ~/.claude/knowledge-vault/ linked into iCloud Drive, so it syncs across my machines. Entries sit in a few broad categories, among them technical, solutions, decisions, domains and tooling, with frontmatter for tags and confidence levels. The plugin ships the nudge from step 5 and the /remember and /recall commands. The nudge’s trigger words fit how I work: I debug out loud and tend to say “turns out” when I’ve found a root cause. A vault-curator agent runs the hygiene pass from step 6. I wrote about why in April 2026, during the debate over memory systems.
The vault is now past 670 knowledge entries, and a structured markdown index navigated directly is still enough for my use: Claude reads the index and follows links without needing semantic search. I know where my own line is because I’ve crossed it once. Knowledge Navigator is a local-first memory system I’m building, where retrieval quality is the product itself. It finds memories by meaning, and a test measures how often the right memory lands in the first few results. Each memory is stored as numbers that capture its meaning, made by an embedding model. Swapping that model means re-processing every stored memory, and that test decides whether the swap ships (evals guide). There, recall is the whole point; for a personal vault, that machinery is overhead.
A team that wants an assistant to answer from its own documents meets the same problem at a larger scale: a stale source gives a confident wrong answer. Building that search, with an owner for each source, is Applied AI work.
Related reading
- How to write a CLAUDE.md file for Claude Code, structure, trimming and on-demand loading for the project layer
- Session craft, when to start fresh, resume, or compact, the full session lifecycle and context management model
- Claude Code pricing: what plans, tokens and models cost, understanding the cost of each memory layer in tokens
- Claude Code skills, hooks, subagents and commands: when to use each, moving knowledge from CLAUDE.md to on-demand skills
- Claude memory systems: the cross-project problem is the real one, the post that started the vault approach
- Claude Code hook examples: turning mistakes into tested rules, for the lessons memory alone doesn’t enforce
Sources
- Claude Code Docs, How Claude remembers your project, official documentation for CLAUDE.md files and auto memory. Documentation
- We Read Claude Code’s Leaked Source. Here’s How Its Memory Actually Works, Zilliz/Milvus, analysis of the v2.1.88 source covering memory architecture and limits. Technical analysis
- Andrej Karpathy, LLM Wiki architecture, the pattern of incrementally building a structured markdown wiki rather than retrieving from raw documents. Primary source
Common questions
Does Claude Code have memory?
Yes, in two forms. CLAUDE.md is a file you write that loads every session. Auto-memory is a folder of notes Claude writes for itself, scoped by default to one project. Neither stores the full conversation, so decisions you need later belong in a file.
How does Claude remember things between sessions?
Not on its own. A new session reloads your CLAUDE.md instructions and the start of auto-memory’s index (the list of notes Claude saved for itself). It does not reload yesterday’s chat. Four places carry the rest: CLAUDE.md for project rules, auto-memory for corrections and preferences, a plan file for a task’s decisions, and a vault (a folder of Markdown notes) for knowledge that applies across projects.
What is the difference between CLAUDE.md and a memory vault?
CLAUDE.md holds standing instructions, for one project or all of them, and loads at the start of every session. A vault is a folder of Markdown notes for knowledge that applies across projects, and Claude reads it when it searches. CLAUDE.md is for rules; the vault is for reusable findings.
How do you build a memory vault that actually gets recalled?
Give each entry a specific title written in the words you would search for later. Then add a routine: save an entry after a debugging session, and search the vault at the start of a task. A short recall trigger in your global CLAUDE.md makes that search a habit.