Memory System
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
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
.mdfile with frontmatter metadata - The directory path is derived from your project's absolute path
Memory Types
Each memory has a type that determines when Claude reads and uses it.
| Type | Purpose | When Saved | Example |
|---|---|---|---|
| user | Who you are — role, preferences, knowledge level | When you share personal/role details | "Senior data engineer, prefers SQL over ORM" |
| feedback | How to work with you — corrections and confirmations | When you correct Claude or confirm an approach | "Don't mock the database in tests — use real DB" |
| project | Ongoing work context — goals, decisions, deadlines | When you share project plans or constraints | "Merge freeze starts 2026-04-10 for mobile release" |
| reference | Pointers to external systems | When you mention tools/URLs/systems | "Bug tracker: Linear project INGEST" |
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
What to Save vs. What to Skip
| Save | Skip |
|---|---|
| User's role, expertise, preferences | Code patterns (derivable from code) |
| Corrections: "don't do X, do Y instead" | Git history (use git log) |
| Confirmed approaches that worked | Debugging solutions (fix is in the code) |
| Project decisions with reasoning | Anything in CLAUDE.md already |
| External system pointers | Ephemeral/in-progress task details |
| Deadlines (with absolute dates) | File paths or architecture (read from code) |
Memory vs. Other Persistence
Claude Code has several ways to persist information. Use the right one:
| Mechanism | Scope | Best For |
|---|---|---|
| Memory | Across conversations | User prefs, feedback, project decisions |
| CLAUDE.md | Every conversation (auto-loaded) | Project rules, architecture, commands |
| Tasks | Current conversation only | Tracking progress on current work |
| Plans | Current conversation only | Implementation strategy before coding |
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.