← All postsHow Does Claude Code Memory Work?

How Does Claude Code Memory Work?

Carlos GarciaCarlos GarciaPublished

How Does Claude Code Memory Work?

Every Claude Code session starts with an empty context window. Nothing from yesterday survives into today on its own, which is why the same correction gets typed into the same project week after week.

Memory is the fix, and it is not one feature. It is two separate systems that happen to be loaded at the same moment, written by different people, stored in different places, and useful for different things.

Most of the confusion about Claude Code memory comes from treating them as one. A rule you want enforced goes in the wrong file. A preference you stated once gets written down somewhere you never look. A file you carefully filled in turns out never to have loaded at all.

This guide covers what each system actually is, every location a memory file can live in and the order they load in, how to set both up, and the specific things that go wrong.

How Does Claude Code Memory Work? The Short Answer

Claude Code carries knowledge across sessions through two mechanisms, and both are loaded at the start of every conversation.

The first is CLAUDE.md files. These are plain markdown files that you write, holding instructions you want Claude to hold in every session: build commands, conventions, project layout, always-do-X rules.

The second is auto memory. These are notes Claude writes for itself, based on your corrections and preferences, stored per repository and indexed in a file called MEMORY.md.

The division is clean. You write instructions; Claude records learnings. If you want to change Claude's behaviour deliberately, you edit a CLAUDE.md. If you want Claude to stop needing the same correction twice, auto memory is already doing that in the background.

The critical caveat applies to both: Claude treats memory as context, not enforced configuration. It reads it and tries to follow it. There is no guarantee.

Running a content operation and not sure it is landing? Get a free SEO audit and see what your pages are actually doing in search.

Free audit

Where do you stand in AI search?

A manual SEO + AI search audit of your site: how ChatGPT, Gemini, Perplexity and Claude read and cite it today, and what to fix first. Report within 48 hours, no credit card.

Get my free audit

Or have it all done: AI SEO services, $999 once

The Two Systems, and Which One You Should Touch

Knowing which system owns a given fact saves a great deal of editing.

CLAUDE.md: Instructions You Write

A CLAUDE.md holds things you would otherwise re-explain. The documentation's own test for when to add something is useful: add it when Claude makes the same mistake a second time, when a code review catches something Claude should have known about this codebase, when you type the same clarification you typed last session, or when a new teammate would need the same context to be productive.

Write instructions concrete enough to verify. "Use 2-space indentation" beats "format code properly". "Run npm test before committing" beats "test your changes". "API handlers live in src/api/handlers/" beats "keep files organized".

The single most valuable line in most CLAUDE.md files is the one that runs the project's tests or type check, because it lets Claude verify its own work as it goes.

Auto Memory: Notes Claude Writes

Auto memory saves four kinds of note, recorded as a type field in each memory file's frontmatter:

  • user: your role, expertise and working preferences
  • feedback: corrections you give Claude and approaches you confirm
  • project: ongoing work, deadlines and decisions Claude cannot derive from the code or git history
  • reference: where to find information outside the project, such as an issue tracker or dashboard

Notably, Claude skips anything it could derive from the codebase itself, such as architecture, file paths or debugging fixes, and skips anything your CLAUDE.md files already say. It also does not save something every session; it decides case by case whether a fact would be useful later.

When you see "Saved 2 memories" or "Recalled 2 memories" in the interface, that is this system working.

Why Neither Is a Guarantee

CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. That is the mechanical reason compliance is not absolute, and it is worth internalising before you write an instruction in capitals and expect it to be obeyed.

If an instruction must run at a specific point, such as before every commit, it does not belong in memory at all. Write it as a hook, which executes as a shell command at a fixed lifecycle event regardless of what Claude decides. To block an action outright, a PreToolUse hook is the tool.

Where CLAUDE.md Files Live, and the Order They Load In

There are four scopes, listed here in load order from broadest to most specific, so a project instruction lands in context after a user instruction:

  • Managed policy, deployed by IT: /Library/Application Support/ClaudeCode/CLAUDE.md on macOS, /etc/claude-code/CLAUDE.md on Linux and WSL, C:\Program Files\ClaudeCode\CLAUDE.md on Windows
  • User instructions, your personal preferences across all projects: ~/.claude/CLAUDE.md
  • Project instructions, shared with the team through source control: ./CLAUDE.md or ./.claude/CLAUDE.md
  • Local instructions, your private per-project notes: ./CLAUDE.local.md, which you should add to .gitignore

Two behaviours matter more than the list itself.

Files above you load at launch; files below you load on demand. Claude Code loads CLAUDE.md and CLAUDE.local.md from your working directory and every directory above it when the session starts. Files in subdirectories are discovered but not loaded until Claude reads, writes or edits a file in that subdirectory, which includes viewing it with a shell command such as cat or head.

Nothing overrides anything. All discovered files are concatenated into context. Across the tree, content runs from the filesystem root down to your working directory, so instructions closer to where you launched Claude are read last. Within a directory, CLAUDE.local.md is appended after CLAUDE.md.

That means a "more specific" file does not win a contradiction. It is simply read later. If two files disagree, Claude may follow either one, so the fix is to remove the contradiction rather than to rely on precedence.

Four scopes, one source of truth. Same idea for your site: get a free SEO audit and see which pages are the real ones.

How to Set Memory Up, Step by Step

Step 1: generate a starting file. Run /init in the project. Claude analyses the codebase and writes a CLAUDE.md with the build commands, test instructions and conventions it can discover. If a CLAUDE.md already exists, /init suggests improvements rather than overwriting it.

Step 2: cut it down. Target under 200 lines per CLAUDE.md file. Longer files consume more context and, counter-intuitively, reduce adherence. Spend your time removing lines rather than adding them.

Step 3: confirm it loaded. Run /context and check the list under Memory files. If the file you expect is not there, Claude cannot see it, and no amount of rewording will help. A subdirectory CLAUDE.md will not appear here, because it loads on demand rather than at launch.

Step 4: add your personal layer. Put preferences that apply to every project in ~/.claude/CLAUDE.md, and private project notes in a gitignored ./CLAUDE.local.md.

Step 5: browse and edit from inside a session. Run /memory. It lists your CLAUDE.md, CLAUDE.local.md and other memory locations across user and project scopes, including entries for files that do not exist yet. Select one to open it in your editor; selecting a file that does not exist creates it first. The same screen holds the auto memory toggle and an option to open the auto memory folder.

Step 6: audit periodically. Run /doctor prompt-audit to have Claude check your instruction files for outdated or conflicting content, references to files and commands that no longer exist, and instructions written for older models. It reports findings with proposed edits and changes nothing until you ask it to apply them. Pass a path to audit one file or directory instead.

Content that nobody finds is content that did not need writing. A free SEO audit shows which of your pages are earning traffic.

Rules, Imports and AGENTS.md

Three mechanisms extend the basic picture, and each solves a different scaling problem.

Imports let one CLAUDE.md pull in another file with @path/to/import syntax. Relative paths resolve against the file containing the import, not the working directory, and imported files can import further files up to four hops deep. Import parsing skips code spans and fenced blocks, so writing a path inside backticks keeps it literal instead of importing it. Worth knowing: imports organise a long file but do not reduce its context cost, because the imported content loads along with it.

An import in a project file that resolves outside your working directory counts as external. The first time Claude Code sees one it shows an approval dialog listing the files, and declining disables them permanently without asking again.

Project rules live as markdown files in .claude/rules/, one topic per file, discovered recursively so you can group them into subdirectories. A rule with no frontmatter loads at launch with the same priority as .claude/CLAUDE.md. A rule with a paths field in YAML frontmatter is path-scoped: it loads only when Claude touches a matching file, which keeps it out of context the rest of the time. paths is the only field Claude Code reads from a rule. Personal rules in ~/.claude/rules/ apply to every project on your machine and load before project rules.

Path-scoped rules are the right answer to the 200-line problem. An instruction that only matters for part of the codebase belongs in a scoped rule, not in the file every session pays for.

AGENTS.md is read as your project instructions when you have no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in your working directory or above it, so a repository already set up for other coding agents works without changes. Your ~/.claude/CLAUDE.md, your managed CLAUDE.md and your .claude/rules/ files do not count for that check and keep loading alongside it. To change the behaviour, type /config and set Project instructions to read both files, only CLAUDE.md, or only your organisation's managed instructions. If you want one file every tool shares, put an @AGENTS.md import at the top of a CLAUDE.md beside it.

When Each Mechanism Is Worth It

  • A fact every session needs: project CLAUDE.md. Build commands, test commands, layout, naming conventions.
  • A preference that follows you between projects: ~/.claude/CLAUDE.md or a user-level rule.
  • Something private to you in a shared repo: CLAUDE.local.md, gitignored.
  • An instruction that only applies to some files: a path-scoped rule in .claude/rules/.
  • A multi-step procedure: a skill, which loads when invoked or when Claude judges it relevant, rather than sitting in context all day.
  • A rule that must be enforced: a hook. Not memory at all.
  • Corrections you keep repeating: leave it to auto memory, or just say "remember that the API tests need a local Redis instance" and it gets saved.

The useful instinct is to ask how often a fact is needed. Always-needed facts belong in CLAUDE.md. Sometimes-needed facts belong in rules or skills. Must-happen actions belong in hooks.

Limitations and Things That Trip People Up

The index has a hard read limit. Only the first 200 lines of MEMORY.md, or the first 25KB, whichever comes first, are loaded at the start of a conversation. Content past that threshold is simply not loaded. Claude keeps the index concise by moving detail into separate topic files, and Claude Code warns it when the file approaches the limit.

Topic files are not loaded at startup. Files such as user_role.md or feedback_testing.md are read on demand when Claude needs them. The index is what gets loaded, which is why it matters that the index stays short.

CLAUDE.md files have a different limit. Claude gets the whole of each launch-time CLAUDE.md as long as it is 4 MiB or smaller. A file over 4 MiB is skipped entirely rather than truncated.

Auto memory is machine-local. Each project gets a directory at ~/.claude/projects/<project>/memory/, and the project path is derived from the git repository, so all worktrees and subdirectories of one repo share it. Files are not shared across machines or cloud environments, so a teammate gets none of your auto memory and neither does your laptop from your desktop.

Auto memory is off by default in some environments. It is on by default in local sessions, and off by default in self-hosted environments outside Claude Tag. The /memory toggle writes autoMemoryEnabled to ~/.claude/settings.json; a project can disable it on its own, and CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 turns it off by environment variable. The toggle also cannot turn it back on inside a background session or a session another Claude Code session started, which is a genuine gotcha if you are automating.

Subagents do not inherit it. The main conversation's auto memory is not loaded into subagents. A fork is the exception, because it inherits the parent conversation outright. A subagent can keep its own separate memory if configured to.

Emphasis is not a strategy. Adding IMPORTANT or capitals to an instruction Claude keeps missing mostly makes Claude over-apply the rule. If a line is getting lost, the file is too long. Fix the length, not the volume.

Version requirements apply to a few of the newer pieces, including the AGENTS.md reading behaviour and /doctor prompt-audit, so if an option described here is missing, check your version before concluding the feature does not exist. All of this reflects the documentation at the time of writing; Claude Code moves quickly, so confirm specifics against the current memory documentation.

Publishing fast and reviewing little? A free SEO audit is a two-minute way to catch what is quietly going wrong.

Memory vs the Alternatives

Memory versus prompting. A good prompt beats a memory file for anything that happens once. Memory earns its place the second time, and only for facts that recur. Where prompting runs out is repetition and guarantees.

Memory versus skills. A skill is a packaged procedure that loads when it is relevant. Memory loads always. Anything that is a workflow rather than a fact belongs in a skill, where it costs nothing until it is needed.

Memory versus hooks. This is the real dividing line. Memory is non-deterministic: Claude reads it and decides. A hook is deterministic: the harness runs it whether Claude wanted to or not. If the consequence of being ignored is unacceptable, you need a hook.

Memory versus the system prompt. For instructions you want at the system prompt level, --append-system-prompt exists. You pass it at launch, which makes it better suited to scripts and automation than to interactive work.

Memory versus another tool's config. If you are arriving from elsewhere, /init reads Cursor rules in .cursor/rules/ or .cursorrules and Copilot rules in .github/copilot-instructions.md, and folds the relevant parts into the generated CLAUDE.md. /import brings a supported agent's wider configuration across, including MCP servers, commands, subagents and skills.

Final Thoughts

Claude Code memory is simpler than it looks once the two systems are separated. You write CLAUDE.md files; Claude writes auto memory. Both load every session. Neither is enforcement.

The practical advice is short. Run /init, then cut the result to under 200 lines. Confirm it loaded with /context rather than assuming. Push anything that only matters sometimes into a path-scoped rule. Leave auto memory alone and let it accumulate. And when an instruction genuinely has to happen, stop writing it in a file and write a hook.

For the wider setup that memory sits inside, our guide to Claude Code best practices covers how instruction files, hooks and skills fit together in one working configuration.

The test of a good CLAUDE.md is not how much it says. It is whether you have stopped typing the same correction into chat.

Want this done for you?

SEO Stuff gets businesses cited by ChatGPT, Gemini, Perplexity and Claude, and ranking in Google. Start with the free audit, a call, or the package.

See where you stand

A free, manual SEO + AI search audit of your site, with a report within 48 hours. No credit card, no sales call.

Get my free audit

Talk it through

A free 15-minute call with the founder about whether AI search is a meaningful opportunity for your business.

Free strategy call

Have it done

The Done-For-You Package: audit, 10 pages of content, 3 DR50+ placements, dashboard. $999 once, delivered in 21 business days.

See the package