Claude Code's Memory Evolution: Auto Memory & PreCompact Hooks Explained

The Problem

Anyone who uses Claude Code long enough hits the same wall: what happens when the Context Window fills up?

Each session has limited context. When conversations get too long, Claude Code automatically compresses (compacts) older content, keeping only summaries. The problem? Compression means lost details. That gnarly bug you spent 30 minutes debugging? After compaction, it might be reduced to “fixed XX issue.”

Starting a new session? Even worse — Claude has zero memory of what happened before.

This creates two core challenges:

  1. Cross-session memory: How does Claude remember what it learned last time?
  2. Compaction protection: How do you preserve full context before compression?

Claude Code now has answers for both.

Auto Memory: Claude Takes Its Own Notes

How It Works

Auto Memory is Claude Code’s new automatic memory system. Unlike CLAUDE.md files that users manually maintain, Auto Memory consists of notes Claude writes for itself.

While working, Claude automatically records:

  • Project patterns: build commands, test conventions, code style
  • Debugging insights: solutions to tricky problems, common error causes
  • Architecture notes: key files, module relationships, important abstractions
  • User preferences: communication style, workflow habits, tool choices

Storage Structure

Each project gets its own memory directory:

~/.claude/projects/<project>/memory/
├── MEMORY.md          # Index file, first 200 lines auto-loaded each session
├── debugging.md       # Detailed debugging pattern notes
├── api-conventions.md # API design decisions
└── ...                # Other topic files

The <project> path is derived from the git repository root, so all subdirectories within the same repo share one memory directory.

Loading Strategy

This is where the design gets clever:

  • MEMORY.md: First 200 lines injected into the system prompt every session
  • Topic files (e.g., debugging.md): Not auto-loaded — Claude reads them on demand

This ensures core memory continuity without wasting precious Context Window space.

Strengths

🟢 Zero maintenance — users don’t need to manually record project details 🟢 Per-project isolation — different projects don’t pollute each other 🟢 Layered design — lightweight index loading, detailed content on demand 🟢 Gets smarter over time — debugging insights persist across sessions

Potential Issues

🔴 Hard 200-line limit — content beyond that isn’t auto-loaded 🔴 Quality is uncontrolled — Claude decides what to remember; it might miss important things 🔴 False memories — incorrect notes will mislead future sessions 🔴 Bloat — files accumulate over time, requiring manual cleanup 🔴 Opacity — users may not know what Claude recorded without checking the directory 🔴 Context cost — 200 lines loaded every startup consumes Context Window

Management

You can manage Auto Memory through:

  • The /memory command to open a file selector
  • Telling Claude directly: “remember that we use pnpm, not npm”
  • Manually editing files in ~/.claude/projects/<project>/memory/

Environment variable control:

export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1  # Force off
export CLAUDE_CODE_DISABLE_AUTO_MEMORY=0  # Force on

PreCompact Hook: Saving Context Before Compression

Auto Memory solves the “what to remember” problem, but there’s one scenario it doesn’t cover — preserving the full context at the moment of compaction.

This solution came from the community. Twitter user @zarazhangrui shared an elegant approach.

Original Approach: /handover Command

Zara first created a custom slash command /handover:

  • User manually runs it before ending a session
  • Claude reviews the entire conversation and generates a “shift-change report” (HANDOVER.md)
  • Covers: what was done, what worked/failed, key decisions, lessons learned, next steps

Think hospital nurse handover notes — making sure the next person knows everything important.

Evolution: Automated PreCompact Hook

Community member @pauloportella_ suggested the key improvement: “turn this into a pre auto compact hook and it will do it automatically.”

This leverages Claude Code’s Hooks system — user-defined scripts that execute at specific lifecycle events.

Configuration

Register the hook in .claude/settings.local.json:

{
  "hooks": {
    "PreCompact": [
      {
        "matcher": "auto",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/pre-compact-handover.py"
          }
        ]
      }
    ]
  }
}

Execution Flow

When Claude Code detects the Context Window is nearly full and triggers automatic compaction:

  1. PreCompact Hook fires — before compression executes
  2. The script receives JSON via stdin, including session_id and transcript_path
  3. It reads transcript_path to get the complete, uncompressed conversation
  4. Calls claude -p to spawn a fresh Claude instance that generates a handover summary
  5. Saves it as HANDOVER-YYYY-MM-DD.md
  6. Compaction proceeds normally

Key Details

The matcher field:

The PreCompact event matcher supports two values:

  • "auto": fires only on automatic compaction (Context Window nearly full)
  • "manual": fires only when user runs /compact
  • "*" or omitted: matches both

Zara chose "auto" — handover docs are only generated on automatic compaction, not manual (since manual compaction implies the user is acting intentionally).

Why a separate instance?

Using claude -p to spawn a new instance for summarization rather than doing it in the current session:

  • The current Context Window is already nearly full — no room for summarization
  • A fresh instance has full Context space to process the conversation transcript

The Hooks System

PreCompact is just one event in Claude Code’s Hooks system. The full lifecycle includes:

EventWhen It Fires
SessionStartSession begins or resumes
UserPromptSubmitUser submits a prompt
PreToolUseBefore a tool call (can block it)
PostToolUseAfter a tool call succeeds
PreCompactBefore context compaction
StopClaude finishes responding
SessionEndSession terminates

Hooks support three handler types:

  • Command: execute a shell script
  • Prompt: send a prompt to a model for single-turn evaluation
  • Agent: spawn a subagent with tool access to verify conditions

Full documentation: Hooks Reference | Hooks Guide

How They Complement Each Other

Auto Memory and PreCompact Hooks solve different layers of the problem:

🔵 Auto Memory: Gradual accumulation — Claude continuously records valuable knowledge during work, available across sessions 🟢 PreCompact Hook: Emergency snapshot — at the exact moment Context gets compressed, the full working state is preserved

They’re not competing — they’re complementary:

  • Auto Memory is long-term memory, recording knowledge
  • PreCompact Handover is a work snapshot, recording state

The best practice is to use both: Auto Memory helps Claude understand your project better over time, while PreCompact Hooks ensure you never lose work progress due to Context compression.

References

If you found this helpful, consider buying me a coffee to support more content like this.

Buy me a coffee