Memory System

Claude Code uses a persistent, file-based memory system that survives across conversations. Memories are stored as Markdown files with YAML frontmatter, organised into types, and loaded into the system prompt at the start of every session.

4
Memory Types
200
Line Limit (Index)
~150
Chars Per Entry
5
Turn Budget

Memory Types

Every memory is categorised into one of four types. Each type has different durability, use cases, and decay behaviour.

Type Purpose Decay Rate Example
User Role, goals, preferences Slow "Senior Go developer, microservices focus"
Feedback Corrections and confirmed approaches Slowest "Always use structured logging, not fmt.Printf"
Project Ongoing work, goals, deadlines Fastest "Merge freeze starts 2026-03-05"
Reference Pointers to external systems Medium "Pipeline bugs tracked in Linear project INGEST"

User Memories

Capture who you are and how you work. These rarely change and persist the longest.

Example: user-preferences.md
--- name: user-preferences description: Developer role and coding preferences type: user --- # User Preferences - Senior Go developer, microservices focus - Prefers table-driven tests over subtests - Uses Australian English spelling (organise, behaviour) - Vim keybindings everywhere

Feedback Memories

The most durable memory type. Structured as a rule, a reason (why), and application guidance (how to apply).

Example: feedback-logging.md
--- name: feedback-logging description: Logging conventions correction type: feedback --- # Rule Always use structured logging via slog, never fmt.Printf. # Why The observability pipeline parses JSON logs. Printf output gets dropped. # How to Apply Import "log/slog" and use slog.Info(), slog.Error() etc.

Project Memories

Short-lived by design. Track deadlines, sprint goals, and in-progress work that becomes stale quickly.

Example: project-sprint.md
--- name: project-sprint description: Current sprint goals and deadlines type: project --- - Merge freeze starts 2026-03-05 - Prioritise auth service migration - API v2 deprecation deadline: 2026-04-15

Reference Memories

Pointers to external systems, documentation, and resources that Claude cannot access directly.

Example: reference-systems.md
--- name: reference-systems description: External system pointers type: reference --- - Pipeline bugs tracked in Linear project INGEST - Deployment runbooks in Notion workspace /eng/runbooks - Staging environment: staging.internal.example.com

File Structure

Memories live in a project-specific directory under ~/.claude/. The path is derived from a hash of your project's absolute path.

Directory Layout
~/.claude/projects/<project-hash>/memory/ MEMORY.md # Index file -- always loaded user-preferences.md # Individual memory file feedback-logging.md # Individual memory file project-sprint.md # Individual memory file reference-systems.md # Individual memory file

MEMORY.md Index File

The index is the gateway to all other memories. It is always loaded into context at the start of every conversation.

200-Line Hard Limit

MEMORY.md is truncated at 200 lines. Anything past line 200 is silently discarded. Keep entries concise (~150 characters each) and prune regularly.

High Impact
MEMORY.md (Index)
# Project Memory ## User - Senior Go developer, prefers table-driven tests [user-preferences.md] - Australian English spelling [user-preferences.md] ## Feedback - Use slog structured logging, never fmt.Printf [feedback-logging.md] ## Project - Merge freeze 2026-03-05, auth migration priority [project-sprint.md] ## Reference - Pipeline bugs in Linear INGEST, runbooks in Notion [reference-systems.md]
Key Detail

MEMORY.md has no YAML frontmatter. It is plain Markdown. Individual memory files use frontmatter, but the index does not.

Individual Memory File Format

Each memory file uses YAML frontmatter with three required fields:

Field Required Description
name Yes Unique identifier for this memory (matches filename without .md)
description Yes Human-readable summary of what the memory contains
type Yes One of: user, feedback, project, reference

Memory Loading: loadMemoryPrompt()

At session start, the memory system builds a prompt section through a specific sequence of operations.

Memory Loading Pipeline 1. Read MEMORY.md Truncate at 200 lines 2. Parse [filename.md] References Extract referenced memory files 3. Load Individual Files Read frontmatter + body content 4. Check File Staleness >1 day old = caveat injected 5. Format as Prompt Section Inject into system prompt Cached until /clear or /compact File Sources ~/.claude/ MEMORY.md projects/ <hash>/ memory/ *.md

The result is cached for the duration of the session. It is only reloaded if you run /clear or /compact.


Auto-Memory Extraction

Claude Code can automatically extract memories from conversations without explicit user action. This runs as a background process with strict constraints.

How It Works

  • Forked sub-agent: A separate agent process is spawned, completely independent of your main conversation
  • 5-turn budget: The extraction agent gets a maximum of 5 turns to identify, categorise, and write memories
  • Sandboxed: Can only write to the memory directory -- no access to your codebase or other files
  • Conflict detection: Skips extraction if you manually wrote to memory in the same turn
  • Throttled: Rate-limited by GrowthBook feature flags (tengu_* namespace)

What Gets Extracted

Extracted Not Extracted
User preferences and coding style Code patterns and implementations
Corrections ("don't do X, do Y instead") Git history and commit details
Project conventions and standards Debugging solutions (too ephemeral)
External system references Content already in CLAUDE.md
Workflow and process decisions Ephemeral task details ("fix this test")
Warning

Auto-extraction has throttling and conflict detection that can cause it to silently skip turns. If you need something remembered reliably, say "remember this" explicitly rather than relying on auto-extraction.


Memory Aging & Staleness

Memories are not treated equally over time. The system applies age-based decay that varies by type.

Memory Type Decay Behaviour Staleness Caveat
Project Decays fastest -- deadlines and sprint goals become stale quickly After ~1 day
Reference Medium decay -- external system pointers may change After ~1 day
User Slow decay -- preferences are stable After ~1 day
Feedback Most durable -- corrections should persist After ~1 day

When a file is older than 1 day, the system injects a caveat into the prompt that makes Claude second-guess the memory's accuracy. To prevent this for stable memories:

Terminal
# Reset modification time to prevent staleness caveat touch ~/.claude/projects/<project-hash>/memory/important_memory.md

Memory Verification

The system includes safeguards to prevent acting on outdated or incorrect memories.

  • File existence check: Verifies the referenced file still exists before loading
  • Content grep: For memories referencing functions or flags, checks they still exist in the codebase
  • Verify before acting: Stale memories include a caveat prompting Claude to verify before relying on them
Practical Tip

If a memory references a function like handleAuth() that was later renamed, the verification step catches this. Claude will re-check the codebase rather than blindly trusting the memory.


Session Memory vs Persistent Memory

These are two distinct systems that serve different purposes.

Aspect Session Memory Persistent Memory
Lifetime Current conversation only Survives across conversations
Storage In-memory (conversation context) Markdown files on disk
Survives /compact Partially (summarised) Yes (reloaded from files)
Survives /clear No Yes (reloaded from files)
Capacity Limited by context window Limited by 200-line index

Agent Memory Scopes

Custom agents can specify which memory scope they operate in. This determines where their memories are stored and who can see them.

Scope Path Visibility
user ~/.claude/memory/ All projects, all agents
project ~/.claude/projects/<hash>/memory/ All agents in this project
local .claude/memory/ (in project root) Only this project checkout
Agent Frontmatter
--- name: my-agent description: Agent with project-scoped memory memory: project # user | project | local ---

Team Memory Sync

In swarm scenarios (multiple agents working in parallel), the local scope stored in .claude/memory/ within the project root can be committed to version control. This enables team-wide memory sharing -- every developer who clones the repository gets the same baseline memories.

Swarm Tip

For coordinated multi-agent work, use local scope so memories are visible to all agents in the same worktree. The project scope stores memories per-user and is not shared through git.


The /memory Command

Access the memory system directly from the CLI.

Terminal
# Open the memory management interface /memory # View current MEMORY.md contents /memory show # Trigger explicit memory save /memory save

Practical Tips

"Remember this" Beats Auto-Extraction

Explicitly telling Claude "remember this" triggers a direct memory write that bypasses throttling, conflict detection, and the GrowthBook feature flag gate. Far more reliable than hoping auto-extraction picks it up.

High Impact

Prune MEMORY.md Regularly

With only 200 lines available, every entry matters. Remove completed project goals, obsolete references, and feedback that has been incorporated into CLAUDE.md. Keep the index lean.

Medium Impact

Touch Files to Reset Staleness

Run touch on memory files that contain stable, long-lived information. This resets the modification timestamp and prevents the staleness caveat from being injected.

Low Impact
Memory vs CLAUDE.md

Use CLAUDE.md for instructions that apply to every conversation (coding standards, project structure, tool preferences). Use memories for things that change over time (deadlines, current sprint focus, corrections from past mistakes). CLAUDE.md is deterministic; memories are probabilistic.