Claude Code memory CLAUDE.md auto memory persistence workflow best practices

Claude Code Memory Persistence: What Actually Works Across Sessions

The Prompt Shelf ·

One of the most common complaints from new Claude Code users goes something like this: “I spent 20 minutes explaining my codebase conventions, Claude was doing exactly what I wanted, and then I started a new session and it forgot everything.”

That frustration comes from a genuine confusion about how Claude Code’s memory actually works. The docs describe four distinct mechanisms, each with different scope, persistence behavior, and tradeoffs. Understanding which layer does what — and which combinations actually hold up in practice — is the difference between a workflow that improves over time and one that resets every Monday morning.

The Four Layers, Plainly Explained

Layer 1: CLAUDE.md (Explicit, Persistent, You Write It)

CLAUDE.md is the most reliable memory layer. It is a plain markdown file that you write and maintain. Claude Code reads it at the start of every session — global settings from ~/.claude/CLAUDE.md, project-specific rules from ./CLAUDE.md in your repo root, and subdirectory-specific overrides in any CLAUDE.md placed deeper in the tree.

What this layer is good for:

  • Coding conventions that never change (“always use named exports”, “never console.log in production code”)
  • Architecture decisions that context-free Claude would otherwise get wrong
  • Commands Claude needs to know but won’t discover on its own (“our deploy command is make ship, not npm run deploy”)
  • Things you’ve already explained three times and don’t want to explain again

What it is not good for:

  • Information that changes frequently (current sprint goal, which PR is in review, what you worked on yesterday)
  • Large amounts of text — CLAUDE.md loads into every session’s context, so a 5,000-token CLAUDE.md is 5,000 tokens of budget spent before you type your first message

The practical ceiling for a productive CLAUDE.md is roughly 1,000–1,500 tokens. Beyond that, you are loading more than Claude can reasonably prioritize, and your context window takes a hit on every session start.

Layer 2: Auto Memory (Automatic, Project-Scoped, Claude Writes It)

Auto Memory, introduced in late 2025, lets Claude write its own notes between sessions without you doing anything. When Claude notices it has corrected the same mistake twice, learned a preference you’ve stated explicitly, or discovered something about your project that would be useful later, it saves a note to ~/.claude/projects/<project>/memory/.

The project path is derived from your git repository root, which means all worktrees and subdirectories of the same repo share one Auto Memory directory. That is intentional — context about your codebase stays with the codebase, not with a particular checkout.

In practice, Auto Memory captures things like:

  • “User prefers early returns over nested if-else chains”
  • “The auth module cannot import from billing — circular dependency risk”
  • “Running tests requires DATABASE_URL to be set; it is not in .env.example

The tradeoff is that you do not control what gets written. Claude decides what is worth remembering. You can review what’s in the memory directory at any time, but it accumulates over sessions and can eventually contain outdated notes alongside useful ones.

Layer 3: MEMORY.md (Explicit, You Write It, Auto-Loaded)

MEMORY.md occupies a slightly awkward middle position. Unlike log files or MCP memory tools, a MEMORY.md placed in your project root does auto-load at session start — Claude treats it similarly to CLAUDE.md. The difference is convention: CLAUDE.md is for rules and instructions, MEMORY.md is for knowledge and state.

Useful content for MEMORY.md:

  • Current architectural state (“we migrated from Redux to Zustand in March, there are still 3 files using the old pattern”)
  • Decisions made with their reasons (“we chose SQLite over Postgres because the app is single-tenant and deploys as a single binary”)
  • Known issues that Claude should not try to “fix” (“the TypeScript error in legacy/loader.ts is intentional — do not touch it”)

Some teams use MEMORY.md as a handoff document — at the end of a work session, they ask Claude to update MEMORY.md with what was accomplished. That pattern works reasonably well, though it requires discipline to maintain.

Layer 4: Auto-Dream (Background Consolidation, Controlled by Feature Flag)

Auto-Dream is the newest layer and still rolling out behind a server-side feature flag. The concept is borrowed from sleep science: a background subagent runs periodically (default: every 24 hours, after at least 5 accumulated Auto Memory sessions) and reorganizes the memory files — archiving stale notes, deduplicating overlapping information, and surfacing what’s been most useful.

The practical effect is that your Auto Memory directory stays coherent over time instead of accumulating contradictory notes. Without Auto-Dream, you might have three notes saying different things about how authentication works because your approach evolved over two months of development. Auto-Dream consolidates those into a single accurate note.

If Auto-Dream is not yet enabled for your account, you can manually trigger the equivalent with /dream in a Claude Code session.

What the Community Has Actually Found Works

After months of people experimenting with these layers in production, a few patterns have emerged as reliably effective.

Start sessions with an explicit memory injection. Before diving into work, add a quick “context reset” at the top of your session: paste in the current state — what feature you’re working on, what’s broken, what you just merged. This feels redundant, but it consistently produces better results than relying on memory layers alone, because Claude’s attention is explicitly directed.

Keep CLAUDE.md short and factual. The teams reporting the best results tend to have CLAUDE.md files under 200 lines. They read like a technical spec sheet, not a training document. Short sentences, bullet points, no explanations unless the reason actively prevents misunderstanding.

Use MEMORY.md for “why” context, CLAUDE.md for “how” rules. This split sounds arbitrary until you realize that “why” context becomes stale (your architecture evolves) while “how” rules stay stable (you still want two-space indentation regardless of what you built last month).

Audit Auto Memory every few weeks. Check ~/.claude/projects/<your-project>/memory/ and scan for outdated notes. Deleting a bad note takes 5 seconds; letting Claude operate on a false assumption for two months costs much more.

Use /compact before switching tasks, not just when you hit limits. Compacting before a major context switch (finishing one feature, starting another) gives Claude’s summarization a cleaner boundary to work with. The resulting summary is more accurate than one produced when the context is at 90% capacity and Claude is compressing under pressure.

The Honest Limitations

Auto Memory is not learning in the way the name implies. It captures discrete facts and preferences, but it does not build a model of your codebase the way you do over months of work. If Claude writes a note that “the payments module uses Stripe,” and you later migrate to Paddle, Auto Memory will not automatically update that note — it will just add a new one, and eventually you have contradictory information until Auto-Dream or manual cleanup resolves it.

CLAUDE.md cannot scale to capture an entire codebase. Some teams try to dump their architecture documentation into CLAUDE.md and then wonder why context gets exhausted quickly. The right tool for large-scale codebase navigation is MCP — specifically, tools that let Claude query your code structure on demand rather than loading it all upfront.

Sessions are still fundamentally stateless. The memory layers mitigate the problem, but they do not eliminate it. For tasks that require deep, evolving context over many sessions — a complex refactor, an exploratory research spike — you will get better results by writing explicit handoff notes at the end of each session than by relying purely on automatic memory.

A Practical Setup That Works

If you want to start with a solid memory architecture without overthinking it:

  1. Create CLAUDE.md in your project root. Fill it with the 10–15 things that, if Claude got wrong, would create the most rework. Keep it under 150 lines.

  2. Create MEMORY.md in your project root. Document current architectural state, major decisions, and known constraints. Update it at the end of any session where significant decisions were made.

  3. Let Auto Memory accumulate for a few weeks before auditing it. You need the data to know what’s actually worth keeping.

  4. If /dream is available in your Claude Code version, run it manually before any large multi-session project. The consolidated memory state gives you a cleaner baseline.

  5. Revisit your CLAUDE.md quarterly. The rules that made sense six months ago might be outdated or superseded by how your project evolved.

The memory system works best when you treat it like documentation — something you actively maintain rather than a passive feature that takes care of itself. Claude Code’s Auto Memory and Auto-Dream handle the automatic parts reasonably well. The part only you can do is knowing which rules and decisions actually matter for your project.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules