--- title: "Claude Code Memory: How CLAUDE.md Actually Works" description: "How Claude Code memory works: the CLAUDE.md hierarchy, auto memory files and caps, session resumption, and where file-based facts go stale." canonical: https://past.dev/blog/claude-code-memory date: 2026-09-02 category: Research authors: The past.dev team --- # Claude Code Memory: How CLAUDE.md Actually Works Claude Code memory is file-based. Every session begins with a fresh [context window](/glossary/context-window), and persistence comes from two documented mechanisms loaded at the start of each conversation: CLAUDE.md instruction files you write, and an auto memory directory Claude maintains for itself ([memory docs](https://code.claude.com/docs/en/memory)). Conversation transcripts are a third, separate store, saved continuously as local JSONL and reloaded by `claude --continue` or `claude --resume` ([sessions docs](https://code.claude.com/docs/en/sessions)). Everything sits on your machine as plain text you can open, edit, or delete. ## Claude Code memory files: the CLAUDE.md hierarchy Claude Code loads CLAUDE.md from four scopes, broadest first ([memory docs](https://code.claude.com/docs/en/memory)): | Scope | Location | |---|---| | Managed policy | `/Library/Application Support/ClaudeCode/CLAUDE.md` (macOS), `/etc/claude-code/CLAUDE.md` (Linux), `C:\Program Files\ClaudeCode\CLAUDE.md` (Windows) | | User | `~/.claude/CLAUDE.md` | | Project | `./CLAUDE.md` or `./.claude/CLAUDE.md` | | Local | `./CLAUDE.local.md`, gitignored personal notes | The resolution rules, all from the same [memory page](https://code.claude.com/docs/en/memory): - Files in the working directory and every directory above it load at launch, concatenated from the filesystem root down, so the file closest to where you launched is read last. - CLAUDE.md files in subdirectories load on demand, when Claude reads files in those directories. - `@path/to/file` anywhere in a CLAUDE.md imports that file into context at launch. Imports recurse to a maximum depth of four hops, and paths inside backticks or code fences stay literal. - A project-level import that resolves outside the working directory triggers a one-time approval dialog before it loads. - Claude Code reads CLAUDE.md rather than AGENTS.md; the documented bridge is a CLAUDE.md containing `@AGENTS.md`, or a symlink. - `.claude/rules/` holds topic files, and a rule with `paths:` frontmatter loads only when Claude works with matching files. Personal rules live in `~/.claude/rules/`. `/init` generates a starting CLAUDE.md from the codebase, `/memory` lists and opens every memory file, and `/context` shows what actually loaded into the current session ([commands docs](https://code.claude.com/docs/en/commands)). ## Auto memory: the notes Claude writes to itself Auto memory is on by default and toggles from `/memory` or the `autoMemoryEnabled` setting, with `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` as the environment-variable off switch ([memory docs](https://code.claude.com/docs/en/memory)). Claude records four documented note types, marked in each file's frontmatter: `user`, `feedback`, `project`, and `reference`. It skips anything derivable from the codebase and anything a CLAUDE.md already says ([memory docs](https://code.claude.com/docs/en/memory)). Storage is one directory per git repository at `~/.claude/projects//memory/`, shared across worktrees of that repository and local to the machine; the docs state files are never shared across machines or cloud environments ([memory docs](https://code.claude.com/docs/en/memory)). Inside sit a `MEMORY.md` index, one line per memory, and a topic file per subject. The caps are specific ([memory docs](https://code.claude.com/docs/en/memory)): - At session start, Claude Code loads the first 200 lines of MEMORY.md or the first 25KB, whichever comes first. Content past that threshold is invisible until something opens the file. - Topic files never load at startup; Claude reads them on demand with its file tools. - A write that pushes MEMORY.md over the limit succeeds, and Claude Code then returns an error telling Claude to rewrite the index, since the excess would be dropped on the next load. - CLAUDE.md has a separate ceiling: loaded in full up to 4 MiB, skipped entirely above that, with guidance to stay under 200 lines per file for adherence. Session transcripts are deleted after a retention period; the memory directory is excluded from that sweep, so entries stay until you or Claude edits them ([memory docs](https://code.claude.com/docs/en/memory)). ## Sessions: what --continue and --resume restore Transcripts are JSONL at `~/.claude/projects//.jsonl`, written continuously as you work ([sessions docs](https://code.claude.com/docs/en/sessions)). `claude --continue` reopens the most recent session in the current directory, `claude --resume` takes a picker, a name, or a session ID, and `/resume` switches conversations from inside a session ([sessions docs](https://code.claude.com/docs/en/sessions)). A resumed session restores the full conversation history including tool calls and results, the model it was using, the agent it ran as, and in the common terminal cases its permission mode ([sessions docs](https://code.claude.com/docs/en/sessions)). Launch flags are a documented exception: `--mcp-config`, `--settings`, and directories added with `--add-dir` must be passed again ([sessions docs](https://code.claude.com/docs/en/sessions)). Default transcript retention is 30 days via the `cleanupPeriodDays` setting ([sessions docs](https://code.claude.com/docs/en/sessions)). Compaction has its own rule: after `/compact`, the project-root CLAUDE.md is re-read from disk and re-injected, while instructions given only in conversation are gone unless someone wrote them to a file ([memory docs](https://code.claude.com/docs/en/memory)). ## Context rather than configuration The docs are explicit that both memory systems are context: Claude reads them and tries to follow them, with no guarantee of strict compliance, and CLAUDE.md content arrives as a user message after the system prompt rather than inside it ([memory docs](https://code.claude.com/docs/en/memory)). For a rule that must always apply, the same page points to PreToolUse [hooks](https://code.claude.com/docs/en/hooks-guide), which run as shell commands at fixed lifecycle events regardless of what Claude decides. The documented saving flows, as of September 2026: ask Claude to remember something and it writes auto memory; ask it to add something to CLAUDE.md and it edits the file; `/memory` opens any memory file in your editor ([memory docs](https://code.claude.com/docs/en/memory)). The current interactive-mode shortcut reference and command list document no `#` memory prefix ([interactive mode](https://code.claude.com/docs/en/interactive-mode), [commands](https://code.claude.com/docs/en/commands)); those three flows are the documented ways in. ## Stale facts: the time axis file memory lacks A CLAUDE.md line is true on the day someone writes it, and the format records nothing else about time: no record of when the fact became true, when it stopped, or what replaced it. The one timestamp in the documented system is the `modified` field Claude Code writes into auto memory frontmatter, an ISO 8601 write time that requires v2.1.214 or later ([memory docs](https://code.claude.com/docs/en/memory)). A write time is ingestion time; it says when the note was saved rather than when the fact happened, a distinction unpacked in [event time vs ingestion time](/guides/event-time-vs-ingestion-time). Updates are manual by design. The docs tell you to review your CLAUDE.md files periodically to remove outdated or conflicting instructions, and warn that when two rules conflict, "Claude may pick one arbitrarily" ([memory docs](https://code.claude.com/docs/en/memory)). [Staleness](/glossary/memory-staleness) is handled by human review, and [supersession](/glossary/fact-supersession) by deletion: a new fact wins only once someone removes the old one. The tooling nudges in that direction: `/doctor` proposes trims for a checked-in CLAUDE.md, and when MEMORY.md nears its cap, Claude Code reminds Claude to merge or drop stale entries ([memory docs](https://code.claude.com/docs/en/memory)). Nothing in the documentation detects that a fact stopped being true. Provenance is similarly thin. The documented frontmatter carries a `type` and a `modified` time; no field links an entry to the session, message, or event that produced it ([memory docs](https://code.claude.com/docs/en/memory)). An entry with no source and no [validity window](/glossary/validity-window) can be read, edited, or deleted, yet never audited back to its origin. In a living codebase most facts change eventually; the failure modes are cataloged in [facts that change over time](/guides/facts-that-change-over-time). ## Common questions ### Does Claude Code have memory? Yes, two documented systems. CLAUDE.md files carry authored instructions through a managed-policy, user, project, and subdirectory hierarchy, and the auto memory directory stores notes Claude writes itself at `~/.claude/projects//memory/`, shared across worktrees and local to the machine. ### Does Claude Code remember previous sessions? Session transcripts persist as JSONL under `~/.claude/projects/` and `--continue` or `--resume` restores a conversation in full. Outside resumed sessions, only what lives in CLAUDE.md and auto memory carries forward. ### How much memory does Claude Code load? MEMORY.md loads its first 200 lines or 25KB into context at session start, with the rest on demand. A CLAUDE.md loads in full up to 4 MiB and is skipped entirely above that. ## For builders: memory with event time past.dev is a memory API for assistants you build. It runs as a managed service or, on an Enterprise agreement, in your own cloud. `POST /api/v1/ingest` accepts timestamped source text, stable source metadata, an audience slug, and an author identity. Once ingestion completes, `POST /api/v1/recall` requires a query and identity and returns ranked documents with dates and source excerpts. Start with the [Memory API quickstart](/docs/memory-api/quickstart) and the [benchmarks](/benchmarks).