Memory System

TL;DR

Claude Code has a file-based memory system at ~/.claude/projects/. Memories persist across conversations so Claude remembers your preferences, project decisions, and feedback without you repeating yourself. Memories are organized by type: user, feedback, project, and reference.

Explain Like I'm 12

Imagine you have a tutor who helps you with homework every day, but they forget everything between sessions. The memory system is like giving the tutor a notebook where they write down what they learn about you: "This student prefers Python," "They like short explanations," "Their project uses PostgreSQL." Next time, the tutor reads the notebook first, so they don't ask the same questions again.

Memory Architecture

Memory system architecture: MEMORY.md index linking to individual memory files by type

How Memory Works

The memory system is file-based — no database, no API. It uses a simple directory structure:

~/.claude/projects/-home-user-myproject/memory/
├── MEMORY.md              # Index file (always loaded)
├── user_role.md           # Individual memory files
├── feedback_testing.md
├── project_deadline.md
└── reference_jira.md
  • MEMORY.md is the index — it's loaded into every conversation automatically
  • Each memory is a separate .md file with frontmatter metadata
  • The directory path is derived from your project's absolute path
Info: MEMORY.md is limited to ~200 lines in context. Keep the index concise — one line per memory with a link to the full file.

Memory Types

Each memory has a type that determines when Claude reads and uses it.

TypePurposeWhen SavedExample
userWho you are — role, preferences, knowledge levelWhen you share personal/role details"Senior data engineer, prefers SQL over ORM"
feedbackHow to work with you — corrections and confirmationsWhen you correct Claude or confirm an approach"Don't mock the database in tests — use real DB"
projectOngoing work context — goals, decisions, deadlinesWhen you share project plans or constraints"Merge freeze starts 2026-04-10 for mobile release"
referencePointers to external systemsWhen you mention tools/URLs/systems"Bug tracker: Linear project INGEST"
Tip: Feedback memories are the most impactful — they prevent Claude from making the same mistake twice. If Claude does something wrong, correcting it creates a feedback memory automatically.

Writing Memories

Creating a memory is a two-step process:

Step 1: Write the Memory File

---
name: testing-approach
description: Integration tests must use real database, not mocks
type: feedback
---

Integration tests must hit a real database, not mocks.

**Why:** Prior incident where mock/prod divergence masked a broken migration.

**How to apply:** When writing tests for database-related code, always use a test database with real schema, never mock the DB layer.

Step 2: Add to MEMORY.md Index

# Memory Index

## Feedback
- [testing-approach.md](testing-approach.md) — Integration tests use real DB, never mocks
Warning: Don't write memory content directly into MEMORY.md. Each entry should be one line (~150 chars) with a link to the full file. The index must stay under 200 lines.

What to Save vs. What to Skip

SaveSkip
User's role, expertise, preferencesCode patterns (derivable from code)
Corrections: "don't do X, do Y instead"Git history (use git log)
Confirmed approaches that workedDebugging solutions (fix is in the code)
Project decisions with reasoningAnything in CLAUDE.md already
External system pointersEphemeral/in-progress task details
Deadlines (with absolute dates)File paths or architecture (read from code)
Info: The key test: "Would this be useful in a future conversation?" If it's only useful right now, don't save it as memory — use tasks or plans instead.

Memory vs. Other Persistence

Claude Code has several ways to persist information. Use the right one:

MechanismScopeBest For
MemoryAcross conversationsUser prefs, feedback, project decisions
CLAUDE.mdEvery conversation (auto-loaded)Project rules, architecture, commands
TasksCurrent conversation onlyTracking progress on current work
PlansCurrent conversation onlyImplementation strategy before coding
Tip: If you find yourself putting the same feedback in CLAUDE.md and memory, keep it in CLAUDE.md — it's loaded first and is more authoritative. Memory is for things that don't belong in the repo.

Best Practices

  • Organize by topic, not time — name files by subject (feedback_testing.md) not date
  • Update stale memories — if a project decision changed, update the memory. Don't let outdated memories mislead Claude.
  • Convert relative dates — "next Thursday" becomes "2026-04-10" so the memory makes sense weeks later
  • Include why — feedback memories with reasoning ("because X broke last time") let Claude judge edge cases
  • Verify before acting — memories can be stale. Claude should check if a remembered file/function still exists before recommending it.
  • Keep the index lean — MEMORY.md should be a quick-scan index. If it's getting long, consolidate related memories.

Test Yourself

What are the four memory types and when would you use each?

user — role, preferences, expertise. feedback — corrections and confirmed approaches. project — decisions, deadlines, goals. reference — pointers to external systems (Jira, Slack channels, dashboards).

Why shouldn't you save code patterns or architecture in memory?

Because these are derivable from the code. Claude can read the current project state directly. Memory of code patterns becomes stale when the code changes, leading to incorrect recommendations.

What's the difference between memory and CLAUDE.md?

CLAUDE.md is version-controlled, shared with the team, and contains project rules/architecture. Memory is personal (per-user), not in the repo, and stores preferences, feedback, and project context that doesn't belong in code.

Why should feedback memories include a "Why" line?

The "Why" lets Claude judge edge cases instead of blindly following the rule. Example: "Don't mock the DB" + "Why: mock/prod divergence broke a migration" — now Claude knows this rule is about data integrity, not a blanket anti-mock stance.

How do you prevent MEMORY.md from becoming too large?

Keep each entry to one line under 150 chars with a link to the full file. The index must stay under 200 lines (truncated after that). Consolidate related memories, remove stale ones, and organize by topic not chronologically.

Interview Questions

How would you design a persistent context system for an AI coding assistant?

Key design decisions: (1) File-based storage for simplicity and portability. (2) Index + detail files pattern — load a lightweight index every session, fetch details on demand. (3) Typed memories (user, feedback, project, reference) for targeted retrieval. (4) Staleness handling — always verify memory against current state before acting. (5) Size limits on index to prevent context bloat. (6) Two-step write to keep index and content in sync.

What's the hardest problem with AI memory systems?

Staleness and conflict resolution. Memory records reflect state at write time but the world changes. A memory saying "use the auth middleware in /lib/auth.js" is wrong if that file was deleted. The system must: (1) treat memories as hints, not facts, (2) verify before recommending, (3) detect conflicts between memory and current state, and (4) update/remove stale memories rather than acting on them.

Why use file-based memory instead of a database?

Simplicity, portability, and transparency. Files are human-readable (Markdown), require no setup, work offline, can be version-controlled, and are easy to manually inspect/edit. A database adds deployment complexity with no real benefit for the small volume of memories (~50-200 records) a project typically has.