Skip to main content
Learn how to split your project memory across multiple files and agents for optimal context usage.

Why Split Memory?

As projects grow, a single CLAUDE.md becomes unwieldy:

Single File Problems

  • 500+ lines loaded every session
  • Package-specific details pollute root context
  • Team members fight over conventions
  • Context budget wasted on irrelevant info

Split Memory Benefits

  • Only load what’s needed
  • Package-specific knowledge isolated
  • Personal preferences separate from team rules
  • Agent-specific memory for specialized tasks

The Three Memory Layers

1

Project Memory (CLAUDE.md)

Shared conventions and build commandsLocation: Root and package directoriesLoaded: Automatically based on working directory
2

Personal Memory (CLAUDE.local.md)

Your preferences and shortcutsLocation: Same as CLAUDE.md, but gitignoredLoaded: Every session in that directory
3

Agent Memory (MEMORY.md)

Agent-specific learnings and patternsLocation: ~/.claude/agent-memory/<agent-name>/Loaded: When that agent runs

Pattern 1: Monorepo Split

Before (Single File)

monorepo/
└── CLAUDE.md  (400 lines, loaded always)

After (Split by Package)

monorepo/
├── CLAUDE.md                 (60 lines - shared only)
├── packages/
│   ├── api/
│   │   ├── CLAUDE.md         (120 lines - API details)
│   │   └── CLAUDE.local.md   (gitignored - your prefs)
│   ├── web/
│   │   ├── CLAUDE.md         (100 lines - frontend)
│   │   └── CLAUDE.local.md
│   └── mobile/
│       └── CLAUDE.md         (80 lines - mobile)
# MyProject Monorepo

## Build
pnpm build          # Build all packages
pnpm test           # Run all tests
pnpm lint           # Lint everything

## Conventions
- TypeScript strict mode
- snake_case for database, camelCase for code
- All API responses follow RFC 7807 for errors

## Packages
- `packages/api` - Express REST API (see packages/api/CLAUDE.md)
- `packages/web` - Next.js frontend (see packages/web/CLAUDE.md)
- `packages/mobile` - React Native app (see packages/mobile/CLAUDE.md)
# API Package

## Run
pnpm dev             # Start with hot reload on :3001
pnpm test            # Jest with --coverage
pnpm db:migrate      # Run Prisma migrations

## Architecture
- Express + Prisma + PostgreSQL
- Auth: JWT with refresh tokens in httpOnly cookies
- Rate limiting: Redis sliding window (10 req/s per IP)

## Database
- Primary: PostgreSQL 15
- Cache: Redis 7
- Schema changes require: pnpm prisma generate

## Endpoints
All endpoints follow:
- `/api/v1/` prefix
- Bearer token auth (except /auth/login)
- Pagination via `?page=X&limit=Y`
- Errors: RFC 7807 Problem Details

## Testing
- Unit: Jest with in-memory DB
- Integration: Real Postgres container
- E2E: Supertest against test server
# My API Preferences

- I prefer verbose test output: `pnpm test -- --verbose`
- Always show SQL queries during dev: set DEBUG=prisma:query
- My local DB runs on port 5433 (not default 5432)

Pattern 2: Agent-Specific Memory

Agents with memory: user, memory: project, or memory: local maintain their own MEMORY.md.

Debugger Agent with Project Memory

---
name: debugger
description: Systematic bug investigation
tools: ["Read", "Glob", "Grep", "Bash"]
memory: project
---
Memory location: ~/.claude/agent-memory/debugger/MEMORY.md What it learns:
  • Common bug patterns in this project
  • Flaky tests and their causes
  • Performance hotspots
  • Error messages and their fixes
The agent auto-curates this file. You don’t manually edit it.

Example Debugger MEMORY.md

# Debugger Agent Memory

## Common Patterns

### "Cannot read property of undefined" in tests
- Usually missing `await` on Prisma calls
- Check test setup: DB might not be seeded
- File: tests/setup.ts has global beforeEach

### Rate limit errors in CI
- Redis not available in CI (uses in-memory mock)
- Mock defined in: src/lib/redis-mock.ts
- Enable with: REDIS_MOCK=true

### Prisma client errors after schema changes
- Forgot to run: pnpm prisma generate
- Auto-fixed by pre-commit hook now

## Known Flaky Tests

- `api/auth.test.ts` - timing-sensitive JWT expiration
  - Fixed by: jest.useFakeTimers()
  
- `api/webhooks.test.ts` - race condition on async processing
  - Fixed by: waitFor() helper

Pattern 3: Multi-Agent with Split Skills

Different agents need different knowledge. Don’t load everything for everyone.
---
name: planner
tools: ["Read", "Glob", "Grep"]
skills: ["architecture-patterns", "project-structure"]
memory: project
---
Loads:
  • CLAUDE.md from current directory
  • Skills: architecture-patterns, project-structure
  • Memory: Past planning decisions
Doesn’t load:
  • API implementation details
  • Test configuration
  • Deployment scripts

Memory Scope Comparison

ScopeLocationLifespanUse Case
user~/.claude/agent-memory/<agent>/Permanent (all projects)Cross-project learnings
project<project-root>/.claude/agent-memory/<agent>/Per projectProject-specific patterns
local<current-dir>/.claude/agent-memory/<agent>/Per directoryPackage-specific knowledge
Rule of thumb:
  • Use user for security patterns (apply everywhere)
  • Use project for codebase patterns (this repo only)
  • Use local for package quirks (this directory only)

Loading Order and Priority

When Claude Code starts, memory loads in this order:
1

1. Ancestor CLAUDE.md files

Walk up from current directory to root, loading each CLAUDE.md
2

2. Ancestor CLAUDE.local.md files

Same walk, load personal preferences
3

3. Agent Memory (if agent specified)

Load first 200 lines of agent’s MEMORY.md
4

4. Skills (agent frontmatter)

Load full content of skills listed in agent config
5

5. Descendant lazy loading

When accessing files in subdirectories, lazy-load their CLAUDE.md
Total context used = Root CLAUDE.md + Package CLAUDE.md + Local preferences + Agent memory + SkillsKeep each layer lean to avoid context bloat.

Optimization Checklist

  • Only shared conventions
  • Build commands (1-2 lines each)
  • High-level architecture
  • Links to package-level docs
  • Package-specific build/test commands
  • Local architecture details
  • Gotchas and quirks
  • Dependencies and integrations
  • Personal shortcuts
  • Editor preferences
  • Local environment config
  • Agent manages this automatically
  • First 200 lines loaded
  • Creates topic files when memory grows
  • Links from MEMORY.md to topic files
  • Preload (agent frontmatter): always in context
  • On-demand (user-invocable): loaded when called
  • Heavy skills: use context: fork for isolation

Real-World Example

Scenario: Working on API endpoint

You run claude from packages/api/src/routes/ What loads:
1. /monorepo/CLAUDE.md                    (60 lines - shared conventions)
2. /monorepo/packages/CLAUDE.md           (if exists)
3. /monorepo/packages/api/CLAUDE.md       (120 lines - API details)
4. /monorepo/packages/api/CLAUDE.local.md (30 lines - your prefs)
5. Agent memory (if using debugger agent) (200 lines - past bugs)

Total: ~410 lines of memory
What does NOT load:
  • packages/web/CLAUDE.md (sibling package)
  • packages/mobile/CLAUDE.md (sibling package)
  • Other agents’ memory files

Scenario: Using planner agent

You run /planner with the agent configured as:
---
name: planner
tools: ["Read", "Glob", "Grep"]
skills: ["architecture-patterns"]
memory: project
---
What loads:
1. Project CLAUDE.md files (same as before)  (~210 lines)
2. Planner agent memory                      (200 lines - past plans)
3. architecture-patterns skill               (150 lines)

Total: ~560 lines
Planner agent has read-only tools and no access to implementation details, keeping context focused.

Migration Guide

1

Audit your current CLAUDE.md

wc -l CLAUDE.md  # Check line count
If > 150 lines, time to split.
2

Identify package boundaries

monorepo/
├── packages/
│   ├── api/      ← Split here
│   ├── web/      ← Split here
│   └── shared/   ← Split here
3

Extract package-specific content

Move API details to packages/api/CLAUDE.mdMove frontend patterns to packages/web/CLAUDE.md
4

Keep root minimal

Root CLAUDE.md should only have:
  • Shared build commands
  • Cross-package conventions
  • Links to package docs
5

Add personal preferences to .local.md

echo "CLAUDE.local.md" >> .gitignore
Move your personal shortcuts to CLAUDE.local.md
6

Configure agents with memory scopes

# .claude/agents/debugger.md
memory: project  # Learns project-specific bugs

Troubleshooting

Cause: You’re running from root, and haven’t accessed files in that package yet.Solution: Either:
  • Run claude from within the package directory
  • Or access a file in that package (triggers descendant loading)
Cause: Agent memory is auto-managed. Manual edits get overwritten.Solution: Let the agent learn naturally. Use CLAUDE.md for manual rules.
Cause: Too many skills preloaded or CLAUDE.md files too long.Solution:
  • Move skills from agent frontmatter to on-demand (user-invocable)
  • Split large CLAUDE.md into smaller files
  • Use context: fork for heavy skills
Cause: Session started before changes, context not refreshed.Solution:
  • Start a new session
  • Or run /compact to reload memory files

Build docs developers (and LLMs) love