Understanding Memory in Claude Code
Every time you start a new Claude Code session, the context window begins empty. Claude knows nothing about your project's architecture, your coding standards, your preferred test runner, or how your team handles deployments. Without memory, you would need to re-explain all of this every single session.
In Claude Code, memory refers to a system that allows the AI to retain and reuse important information — settings, rules, and contextual details — across coding sessions. The purpose of memory is to improve workflow efficiency and maintain consistency over time.
Memory is primarily managed through special files called CLAUDE.md files. These files store instructions and preferences that Claude Code loads at the start of each session and uses to guide its behavior throughout the interaction. Think of them as a briefing document: before Claude does any work, it reads every applicable CLAUDE.md file and builds its understanding of how you want it to behave.
This article explains Claude Code's full memory system — the different types of memory, where each type lives, how Claude discovers and loads them, and the hierarchy that determines priority when instructions conflict. By the end, you will have a clear mental model for how memory works and how to structure it effectively.
Two Memory Systems
CLAUDE.md vs. Auto Memory
Claude Code actually has two complementary memory systems. Both are loaded at the start of every conversation, but they serve different purposes:
| Aspect | CLAUDE.md Files | Auto Memory |
|---|---|---|
| Who writes it | You (the developer) | Claude (automatically) |
| What it contains | Instructions and rules | Learnings and patterns |
| Scope | Project, user, or organization | Per working tree / per project |
| Use for | Coding standards, workflows, project architecture | Build commands, debugging insights, preferences Claude discovers |
CLAUDE.md files are instructions you write and maintain manually. You have full control over their content, and they are loaded into context at the start of every session. This is the primary memory mechanism and the focus of this article.
Auto memory lets Claude accumulate knowledge across sessions without you writing anything. Claude saves notes for itself as it works — build commands, debugging insights, code style preferences, and workflow habits. Auto memory is stored at ~/.claude/projects/<project>/memory/ and the first 200 lines (or 25KB) of its index file are loaded at session start. You can browse and edit auto memory files at any time using the /memory command.
Types of Memory
Granularity: From Personal to Organization-Wide
Memory in Claude Code is granular and can be defined at different levels. Each level has a specific purpose, a specific file location, and a specific scope. Understanding these levels is essential for structuring your instructions correctly.
User Memory
User-level memory is stored in your home directory at ~/.claude/CLAUDE.md. This file contains personal preferences that apply across all projects on your machine. It is not shared with anyone else and is not committed to version control.
Examples of what goes in user memory:
- Coding style preferences (indentation, naming conventions)
- Frequently used workflows and shortcuts
- Communication preferences (how you want Claude to respond)
- Personal tooling habits that should remain consistent regardless of the project
Here is an example of a user-level CLAUDE.md:
Because this file is loaded into every session regardless of the project, it ensures Claude always follows your personal habits.
Project Memory
Project-level memory is stored as a ./CLAUDE.md file (or ./.claude/CLAUDE.md) within a project directory. This memory contains team-shared rules and project-specific context. It is committed to version control so that every team member — and every CI/CD pipeline running Claude — gets the same instructions.
A good project CLAUDE.md typically includes:
- Build and test commands — How to install dependencies, run tests, lint, and build
- Code style conventions — Formatting rules, naming conventions, import ordering
- Architecture overview — Key directories, important files, how modules connect
- Workflow rules — Branch naming, commit message format, PR process
- Do's and don'ts — Common mistakes to avoid, patterns to prefer
Here is an example for an ASP.NET Core Web API project:
Project Local Memory
The CLAUDE.local.md file sits in your project root alongside CLAUDE.md, but it is not committed to version control. It is automatically ignored by Git. Use it for personal overrides specific to one project:
- Personal context such as "I am working on the payments module this sprint"
- Overrides that conflict with the shared CLAUDE.md
- Temporary notes or debugging context
- Local environment specifics (e.g., local API URLs, database port differences)
Project Rules
For larger projects, memory can be broken into topic-specific rule files stored in the .claude/rules/ directory. Each file should cover one topic, with a descriptive filename like testing.md or api-design.md. These files are shared across the team and committed to version control.
Rules can also be scoped to specific file paths using YAML frontmatter. Path-scoped rules only load into context when Claude is working with files that match the specified patterns, reducing noise and saving context space:
Rules without a paths field are loaded unconditionally at launch and apply to all files. You can also create personal rules at ~/.claude/rules/ that apply to every project on your machine.
Managed Policy (Organization-Level Memory)
Organization-wide instructions are managed by IT or DevOps teams and deployed centrally. These are stored at system-level paths that vary by operating system:
| Operating System | Location |
|---|---|
| macOS | /Library/Application Support/ClaudeCode/CLAUDE.md |
| Linux / WSL | /etc/claude-code/CLAUDE.md |
| Windows | C:\Program Files\ClaudeCode\CLAUDE.md |
Managed policy is used for company-wide coding standards, security policies, and compliance requirements. It applies to all users within the organization and cannot be overridden or excluded by individual settings. Organizations typically deploy this file using MDM, Group Policy, Ansible, or similar configuration management tools.
It is important to understand the distinction between managed CLAUDE.md and managed settings. Settings enforce technical rules (blocking specific tools, enforcing sandbox isolation). A managed CLAUDE.md provides behavioral guidance — it shapes how Claude acts, but it is not a hard enforcement layer.
The Memory Hierarchy
How Priority Works
Claude Code organizes memory into multiple levels, each serving a distinct purpose. When instructions from different levels conflict, priority determines which instruction wins. Higher levels take precedence and cannot be overridden by lower ones:
| Level | Type | Location | Scope | Override Behavior |
|---|---|---|---|---|
| 1 (Highest) | Managed Policy | System-managed path | Entire organization | Cannot be overridden or excluded |
| 2 | User Memory | ~/.claude/CLAUDE.md | Personal — all projects | Applies globally across all your projects |
| 3 | Project Memory | ./CLAUDE.md or ./.claude/CLAUDE.md | Shared via version control | More specific files take precedence |
| 4 | Project Rules | ./.claude/rules/*.md | Shared via version control | Path-scoped rules only load when relevant |
| 5 | Project Local Memory | ./CLAUDE.local.md | Personal — current project only | Gitignored; last read at each directory level |
All discovered files are concatenated into context rather than overriding each other. Within each directory, CLAUDE.local.md is appended after CLAUDE.md, so when instructions conflict, your personal notes are the last thing Claude reads at that level. When conflicts occur at the same level, more specific files — those closer to the current working directory — take precedence.
How Claude Code Reads Memory
Upward Discovery
Claude Code loads memory using a hierarchical and layered approach. When you launch Claude Code, it begins searching for memory files from the current working directory and continues upward through parent directories toward the file system root. All applicable memory files that are discovered are loaded into the session and combined to form the working context.
At each directory level, it checks for:
CLAUDE.md(or.claude/CLAUDE.md)CLAUDE.local.md
Both files, if present, are loaded at that level, with CLAUDE.local.md appended after CLAUDE.md.
A Concrete Example
Consider the following directory structure:
If Claude Code is started from:
The following memory files are loaded into the session:
frontend/CLAUDE.md— current directory (most specific)my-company/CLAUDE.md— parent directory~/.claude/CLAUDE.md— user-level memory
All three files are combined to form the effective context. Claude reads the instructions from each file and follows them together. If two files give conflicting guidance, the more specific file (closer to the current directory) generally takes precedence.
Subdirectory Discovery
CLAUDE.md files in subdirectories under your current working directory are not loaded at launch. Instead, they are included when Claude reads files in those subdirectories during the session. This lazy loading prevents unnecessary instructions from cluttering the context when they are not relevant.
What Happens After /compact
When you use the /compact command to compress your context, the project-root CLAUDE.md survives compaction — Claude re-reads it from disk and re-injects it into the session. However, nested CLAUDE.md files from subdirectories are not re-injected automatically; they reload the next time Claude reads a file in that subdirectory.
If an instruction disappears after compaction, it was either given only in conversation (not saved to a file) or it lives in a nested CLAUDE.md that hasn't reloaded yet. The lesson: add important instructions to CLAUDE.md to make them persist.
Dynamic Imports with @ Syntax
Pulling in External Context
Sometimes your instructions reference external documentation or conventions that live in separate files. Instead of duplicating that content into CLAUDE.md, you can use the @ import syntax to pull it in dynamically at session start:
When Claude Code loads this CLAUDE.md, it reads the referenced files and injects their content into context. The @ prefix tells Claude Code to resolve the path relative to the file that contains the import.
Import Rules
- Paths are relative to the file containing the
@directive - Absolute paths are also allowed
- Recursive imports are supported — an imported file can itself contain
@imports, up to a maximum depth of 5 hops - Missing files are silently skipped — if a referenced file does not exist, Claude Code continues without error
- The first time Claude Code encounters external imports in a project, it shows an approval dialog listing the files
This is particularly useful when you need to share instructions with other AI coding tools. If your repository already uses an AGENTS.md file, you can import it into your CLAUDE.md so both tools read the same instructions without duplication:
Writing Effective Memory Instructions
Best Practices
CLAUDE.md files are loaded into the context window at the start of every session, consuming tokens alongside your conversation. How you write instructions directly affects how reliably Claude follows them. Here are the key guidelines from the official documentation:
- Be specific, not vague — Write
Use xUnit, not NUnitinstead ofUse the right testing framework - Be concise — Use short phrases and bullet points. Target under 200 lines per CLAUDE.md file
- Use Markdown headers and lists — Structure helps Claude parse the content quickly
- Commit the project CLAUDE.md to version control — It should be a shared team resource
- Prune regularly — Remove rules that are no longer relevant. Stale instructions confuse the model
- Test your instructions — After editing, start a new session and verify Claude follows the rules
If your CLAUDE.md is growing beyond 200 lines, move detailed content into separate files referenced with @path imports or split your instructions across .claude/rules/ files. Overly long files consume more context and reduce adherence.
Treat It Like a Briefing Document
A helpful mental model: treat CLAUDE.md as the document you would hand to a new team member on their first day. It should contain everything they need to be productive — build commands, conventions, architecture, do's and don'ts — without overwhelming them with details they can look up later. If you would not re-explain something every session, it belongs in CLAUDE.md.
When to Add to CLAUDE.md
The official documentation recommends adding to CLAUDE.md when:
- Claude makes the same mistake a second time
- A code review catches something Claude should have known about the codebase
- You type the same correction or clarification you typed last session
- A new teammate would need the same context to be productive
Using the /init and /memory Commands
Generating a Starter CLAUDE.md with /init
If you are starting fresh, Claude Code can generate a starter CLAUDE.md for you. Run:
Claude will scan your project's file structure, package files, and configuration, then generate a CLAUDE.md with reasonable defaults. You should always review and refine the output — the generated file is a starting point, not a final product.
You can also set the environment variable CLAUDE_CODE_NEW_INIT=1 to enable an interactive multi-phase flow where /init asks which artifacts to set up (CLAUDE.md files, skills, and hooks), explores your codebase, and presents a reviewable proposal before writing any files.
Browsing Memory with /memory
The /memory command lists all CLAUDE.md, CLAUDE.local.md, and rules files loaded in your current session. It also lets you toggle auto memory on or off and provides a link to open the auto memory folder. You can select any file from the list to open it in your editor.
This is also the primary tool for debugging memory issues. If Claude is not following an instruction, run /memory to verify the file is being loaded. If a file is not listed, Claude cannot see it.
Troubleshooting Memory
Claude Is Not Following My CLAUDE.md
CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. Claude reads it and tries to follow it, but there is no guarantee of strict compliance — especially for vague or conflicting instructions. To debug:
- Run
/memoryto verify your files are being loaded - Check that the CLAUDE.md is in a location that gets loaded for your session
- Make instructions more specific —
Use 4-space indentationworks better thanFormat code nicely - Look for conflicting instructions across CLAUDE.md files — if two files give different guidance, Claude may pick one arbitrarily
CLAUDE.md Is Too Large
Files over 200 lines consume more context and may reduce adherence. Move detailed content into separate files referenced with @path imports, or split your instructions across .claude/rules/ files. Keep the main CLAUDE.md focused on the most critical rules.
Putting It All Together
A Complete Memory Setup
Here is what a well-structured memory setup looks like for a team working on an ASP.NET Core project:
When you launch Claude Code from this project directory, all applicable files are discovered, loaded, and combined into the session context. The managed policy cannot be overridden, user preferences apply globally, project rules are shared with the team, and your local overrides keep your personal setup separate.
Memory is the foundation of consistent, productive sessions with Claude Code. Invest a few minutes to set it up once, and every future session starts with Claude already knowing how to work in your project.