Claude Code Auto Memory: What Claude Remembers and Why

Notes Claude writes for itself based on your corrections and preferences, stored as markdown per repository. It records four kinds of note: who you are, feedback you gave, project context that cannot be derived from the code, and where to find information outside the project. It is on by default and every file is plain text you can edit.
In a memory directory under your Claude config directory, one per project, with an index file and one file per topic. The project name comes from the git repository, so every worktree of the same repo shares one directory. A settings key can move the location, and it is machine-local rather than synced.
Only the index file, capped at the first 200 lines or 25KB, whichever comes first. Topic files are read on demand when Claude needs them. Content past the limit is not loaded, so an oversized index silently loses whatever falls below the cut — which is the first thing to check if memories seem to stop working.
Run the memory command, which lists your memory locations, lets you open any file in your editor, and gives you a route into the memory folder. Everything is plain markdown, so you can read, edit or delete any of it. The transcript retention sweep excludes this directory, so memories persist until changed.
Toggle it in the memory command, which writes the setting to your user settings file, or set that same key in a single project's settings to disable it there only. There is also an environment variable that disables it. Note that memory is context rather than enforcement — for a rule that must hold, use a hook.

Key Takeaway
Auto memory is a set of markdown notes Claude writes for itself, per repository, from your corrections and preferences. Only the index file is loaded at the start of every session — the first 200 lines or 25KB, whichever comes first — and the topic files are read on demand. It is on by default, and every file is plain text you can read, edit or delete.
The first time I noticed it, a session I had just started already knew that I prefer the build and typecheck to run before anything is pushed, and that I do not want screenshots as verification. I had said both things weeks earlier, in a different session, once each. Nothing about that is magic, and knowing how it works turns out to matter, because the notes are files and files can be wrong.
This post covers the two memory systems and which one writes what, the four kinds of note Claude saves and what it deliberately skips, where the files live and what boundaries they do not cross, the index limit that decides what actually loads, how to audit and edit them, and how to turn the whole thing off per project or entirely.
Claude Code has two complementary memory mechanisms, both loaded at the start of every conversation, and both treated as context rather than enforced configuration. That last point matters more than it sounds: neither one is a guarantee. To block an action regardless of what Claude decides, the answer is a hook, not a note.
The two systems side by side:
| Property | CLAUDE.md files | Auto memory |
|---|---|---|
| Who writes it | You | Claude |
| What it holds | Instructions and rules — standards, workflows, architecture | Learnings and patterns — your preferences and the corrections you gave |
| Scope | Project, user or organisation, in a documented load order | Per repository, shared across every worktree of it |
Claude records the kind in a frontmatter field, and the four are deliberately narrow. Knowing them is the fastest way to predict whether something you say will be remembered:
Two exclusions do most of the work of keeping this useful. Claude skips anything derivable from the codebase — architecture, file paths, how a bug was fixed — and anything your CLAUDE.md files already say. It also does not save something every session; it decides whether the information would help in a future conversation.
Each project gets a directory under your Claude config directory, and the project name comes from the git repository rather than the working directory — which is why every worktree of the same repo shares one set of memories. Auto memory is machine-local: it does not travel to another machine or into a cloud environment.
~/.claude/projects/<project>/memory/
├── MEMORY.md # the index. First 200 lines OR 25KB,
│ # whichever comes first, loaded into
│ # EVERY session
├── user_role.md # one memory per topic file
├── feedback_testing.md # read on demand, never at startup
└── …
# <project> comes from the GIT REPOSITORY, so every worktree and
# subdirectory of the same repo shares one memory directory.
# Outside a repo, the project root is used instead.
{ "autoMemoryDirectory": "~/my-custom-memory-dir" }
# absolute or ~/ only; honoured from any settings scope, and in a
# project settings file it follows the workspace trust rule
# The retention sweep that deletes old transcripts EXCLUDES this
# directory. Memories stay until you or Claude edits them.Only the index file loads at session start, capped at 200 lines or 25KB. Topic files are read on demand with ordinary file tools when Claude needs them. That design is what keeps the whole system cheap — one concise index in every session, detail fetched only when relevant — and it is why the index has a rule the topic files do not.
Content past the limit is not loaded, silently. When the index gets close, Claude Code reminds Claude to shorten it: one line per entry, detail moved into topic files, stale entries merged or dropped. When it goes over, the write still succeeds but an error tells Claude to rewrite the index, because everything past the cap is dropped on the next load. If your memories seem to have stopped working, an oversized index is the first thing to check.
Everything here is plain markdown you own. The memory command lists your CLAUDE.md and memory locations, opens any of them in your editor, toggles auto memory, and gives you a way into the memory folder itself. Reading what has accumulated after a few weeks is worth doing at least once — some of it will be more specific than you expected.
/memory # browse and open every memory file, and
# toggle auto memory on or off
{ "autoMemoryEnabled": false } # user settings, or one project's
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1
# Ask for something to be remembered in plain language:
# "always use pnpm, not npm"
# "remember that the API tests need a local Redis"
#
# To put it in CLAUDE.md instead, say so: "add this to CLAUDE.md".
# The two are different systems and Claude picks the one you name.You can also just ask. Saying that you always use one package manager rather than another, or that the API tests need a local database running, gets saved. If you want the instruction in CLAUDE.md instead — because it should be shared with your team through version control — say that explicitly, and Claude puts it there rather than in its own notes.
The main conversation's auto memory is not loaded into subagents. The exception is a fork, which inherits the parent conversation and system prompt and therefore carries it along. A subagent can maintain its own auto memory when configured to, and that is a separate directory — so a specialised reviewer accumulates its own learnings without mixing them into yours.
One practical detail that makes this safer to rely on than it first appears: the retention sweep that deletes old session transcripts explicitly excludes the memory directory. Your memories are not quietly cleaned up after a month with everything else. They stay until you or Claude edits or deletes them, which also means a wrong one stays wrong until somebody notices.
Auto memory is context, not configuration, and it will not enforce anything. If a rule must hold at a specific moment — before every commit, after each file edit — write it as a hook, which runs as a shell command at a fixed lifecycle event regardless of what Claude decides. Memory makes Claude more likely to do the right thing; a hook makes the wrong thing impossible. They solve different problems and a project that is serious about a rule usually needs both.
Read your memory directory once, early, because it tells you what Claude thinks you want and that is worth checking against what you actually want. Keep the index short — it is the only part that costs you context in every session. And when something absolutely must happen, do not rely on a note about it: write the hook, and let memory handle the preferences it is good at.
Sources & further reading