Skip to content

Memory

Claude Code’s memory model has two distinct mechanisms with confusingly similar names. The case convention is meaningful, and treating them as one thing is the source of most confusion when readers first encounter them.

  • MEMORY.md (uppercase) — auto-memory. User-level and managed by Claude Code. Lives at ~/.claude/projects/<machine-path>/memory/MEMORY.md. The path looks project-scoped but isn’t — it’s a storage convention, and the file applies across every project on this machine. Claude Code loads it at session start and can append entries during conversations.
  • memory.md (lowercase) — the decision log. Project-level and manually maintained. Lives at <repo>/memory.md, committed to the repo, shared with anyone working on the project. You write entries by hand to capture why decisions were made.

One word, two mechanisms: a personal, always-loaded notebook (auto-memory) and a project-specific, append-only architecture log (decision log).

~/.claude/projects/<machine-path>/memory/MEMORY.md is the index of Claude Code’s auto-memory. Individual memory files live in the same folder; the index lists each one with a short hook line. Claude Code reads the index at session start and pulls in individual files as topics surface during the conversation.

The folder is yours to inspect and edit. Open the files directly when you want to verify, correct, or remove an entry.

Four categories of information:

  • User memories — your role, preferences, responsibilities, knowledge. Helps Claude tailor responses to who you are.
  • Feedback memories — corrections you’ve given Claude, and approaches you’ve explicitly validated. Stops you having to give the same guidance twice.
  • Project memories — ongoing initiatives, deadlines, owners, motivations behind active work. Captures context that isn’t in the code.
  • Reference memories — pointers to external systems where information lives (a Linear project, a Grafana board, a Slack channel). Tells Claude where to look, not what’s there.

Each entry is its own file with a frontmatter block carrying name, description, and type. The body holds the content. The MEMORY.md index is a one-line summary per file — a scannable table of contents.

The quality of an auto-entry depends on the conversation pattern that produced it. The patterns that produce good entries:

  • Be explicit when the rule is important. “Remember that X” or “Save this as a preference” produces a deliberate entry rather than an inferred one.
  • Give the rationale alongside the rule. “Don’t mock the database in these tests — mocks passed last quarter while the prod migration failed.” The why-line is what lets Claude (or you, later) judge edge cases.
  • Be specific, not vague. “I prefer concise responses” produces a vague entry; “for code review comments, no trailing summary line” produces a useful one. Vague entries that produce inconsistent behaviour are worse than no entry.

Auto-entries land on disk; you can correct, delete, or rewrite them at any time. When something’s wrong:

  • Rule is wrong. Open the file under ~/.claude/projects/<path>/memory/ and edit it. Keep the frontmatter’s name and description aligned with the body.
  • Category is wrong. Change the type field — same content, different category.
  • No longer applies. Delete the file, then remove the corresponding line from MEMORY.md (the index).

If you find yourself frequently correcting entries Claude wrote, the conversation patterns producing them are weak — adjust how you give the rule.

Auto-memory is right for user-level context that’s worth referencing but doesn’t need to be in front of Claude every session. Three signals an entry should harden into something more permanent:

  • You want it loaded every session, not just relevant ones. Promote to ~/.claude/CLAUDE.md. Auto-memory loads when the topic surfaces; CLAUDE.md loads always.
  • It’s project-specific and team-shared. Promote to project-level CLAUDE.md (committed, governs everyone working on the repo) or the project’s memory.md (committed decision log).
  • It’s architectural history, not personal context. Move to the project’s memory.md. Auto-memory is what you carry across projects; architectural records belong with the project.

Hardened entries are more expensive — always loaded, committed to a repo — but more reliable. Auto-memory is cheaper but conditional on Claude surfacing it.

memory.md (lowercase, in the project root) is the project’s decision log. Every non-obvious choice — why this library, why this pattern, why we abandoned that approach — gets a dated entry. Months later, when you come back to the project (or hand it to someone else), memory.md is what answers the question “why did we do it this way?”

CLAUDE.md and memory.md are complementary. They capture different things and serve different purposes.

CLAUDE.md captures the current rules — what to do now. It’s a system prompt that loads on every session and shapes Claude’s behaviour. When a rule changes, the old version is overwritten.

memory.md captures the historical decisions — why we landed on the current rules. It’s append-only. When a decision changes, the new decision is logged as a new entry, and the old entry stays. The log is the trail.

The relationship matters: when you make a non-obvious architectural choice, the rule it produces goes in CLAUDE.md (so Claude follows it on every session) and the rationale goes in memory.md (so future-you can reconstruct why).

Three categories of decision reliably earn their place:

Architectural choices that aren’t obvious from the code. Why you picked Server Actions over API routes. Why state management uses Context rather than Zustand. Why the data layer is split this way. These are decisions that the code reflects but doesn’t explain — and “why is it built this way?” is the question you’ll have six months later.

Trade-offs you made deliberately. Anywhere you considered alternatives and rejected them. The fact that you rejected something is more valuable than the fact that you chose what you chose, because it stops future-you (or future-Claude) from re-litigating the same decision.

Reversals. When you change direction, the entry should explain what you tried, why it didn’t work, and what you’re doing instead. Reversals are the highest-leverage entries — they’re the ones that prevent the same wrong path being walked twice.

Three categories that look tempting but bloat the log:

Routine implementation steps. “Added a Header component” doesn’t earn an entry. The code shows you did that. memory.md is for why, not what.

Decisions the code already explains. “Used TypeScript strict mode” doesn’t need an entry — tsconfig.json shows it. “Used TypeScript strict mode despite the team’s previous resistance, because we hit three runtime type errors in the last sprint” does, because the why isn’t in the code.

Speculative future work. “We might add multi-tenancy later” isn’t a decision; it’s a thought. Decisions go in the log. Thoughts go in the PRD’s Out of Scope section, or in a dedicated future-work doc.

Two examples, one good and one bad. Use the good one as a template.

## 2026-04-12 — Switched from Tanstack Query to Server Actions
**Decision:** Removed Tanstack Query from the dashboard pages. Data fetching now uses Server Actions invoked from Server Components.
**Why:**
- Dashboard pages don't need client-side cache invalidation — they're read-mostly
- Tanstack Query was adding ~12kb to the client bundle for marginal benefit
- Server Actions match the rest of the data layer, fewer patterns to maintain
**Alternatives considered:**
- Keep Tanstack Query but only on pages that need polling — rejected, the inconsistency would confuse contributors
- Swap to SWR — same bundle cost, no real win
**Implications:** Anything that genuinely needs client-side cache (e.g. real-time collaboration, future feature) will need Tanstack Query reintroduced or a different solution. Flag at that point.

The entry works because it’s specific, dated, and structured. The decision is one line; the rationale is enumerable. Alternatives considered are listed so the next person doesn’t waste time evaluating them again. The implications section flags the boundary — here’s where this decision will need revisiting.

## Updated state management
Refactored the state management because the previous approach wasn't working
well. Used a different library that seems better. Will see how it goes.

Five problems in three sentences:

  • Undated. When did this happen? Was it before or after the routing change?
  • Vague. Which state management? “Different library” — which library?
  • No rationale. “Wasn’t working well” doesn’t explain anything. Wasn’t working how?
  • No alternatives. Did you consider the obvious options? Or did you just grab the first thing?
  • No commitment. “Will see how it goes” reads as a draft. Either commit to the decision or don’t make it.

Six months from now, this entry tells you nothing. You’ll have to read the git history, re-derive the rationale, and probably re-evaluate the same alternatives.

memory.md is append-only, but it still benefits from review. The maintenance habits worth forming:

  • Update at decision points. When you make a non-obvious choice — including ones you make in conversation with Claude — the entry goes in immediately, not “later”. Later doesn’t happen.
  • Reread at session start when returning to a project. When you come back to a project after time away, scan memory.md before starting work. The decisions that were obvious when you left will need refreshing; the log is the fastest path back into context.
  • Review monthly, but don’t prune. A monthly pass through recent entries catches the ones that need clarification (“what did past-me mean by that?”) or follow-up flagging (“we said we’d revisit this in three months — it’s been three months”). Don’t delete entries — even reversed ones stay, because the reversal itself is the valuable record. If an entry is genuinely confusing, add a clarifying entry below it rather than editing the original.
  • Cross-link to detailed records when needed. If a decision warrants more than ~150 words of explanation, the full record goes in docs/decisions/ and memory.md carries a one-line summary plus a link. The log stays scannable; the depth lives where it can grow.

The point of all four habits: the log is most valuable when you trust it. Every entry that’s accurate, dated, and specific reinforces that trust. Every entry that’s vague or stale erodes it.

MEMORY.md carries you across projects; memory.md records one project’s decisions. When something noteworthy happens in conversation, the right home depends on its scope:

  • If it shapes how you want to work in general, it’s auto-memory.
  • If it shapes how this project works specifically, it’s a memory.md entry.
  • If it’s a constraint that should govern every session in this project, it’s CLAUDE.md.

The mechanisms compose. Auto-memory carries personal context with you across machines and projects; CLAUDE.md shapes how Claude behaves inside this project; memory.md records why the project ended up the way it is.