Claude Code’s memory system has four layers, each doing something different. The overview of how those layers work is useful background. What this guide covers is different: how to build a memory setup that does not require constant maintenance, survives long gaps between sessions, and gets more useful over time rather than accumulating noise.
Browse CLAUDE.md and MEMORY.md examples from real projects in our gallery.
The Problem with Most Memory Setups
Most developers do one of two things:
- Write a thorough CLAUDE.md, then never touch it again
- Rely entirely on Auto Memory and hope Claude captures what matters
Both approaches break down. Option 1 leaves stale context in the file as the project evolves. Option 2 produces a memory directory that mixes current information with outdated notes from six months ago, with no clear signal about which is which.
A working memory system needs: explicit maintenance touchpoints, a clear separation between “rules” (CLAUDE.md) and “knowledge” (MEMORY.md), and a curation strategy for Auto Memory.
The Three-File Architecture
The pattern that works best for active projects uses three files:
CLAUDE.md — Stable rules that change rarely. Conventions, tool preferences, things Claude should always do or never do. Target: under 1,000 tokens. Review quarterly.
MEMORY.md — Current project state. Architecture decisions with their rationale, what was recently changed, known issues, what is in flight. This file changes frequently. Review every 2–4 weeks.
CONTEXT.md — Session-specific handoffs. What you accomplished this session, what was left open, what the next session should pick up. This file changes every session. Claude updates it at the end of each session.
The separation matters because the maintenance cadence for each file is different. Mixing stable rules with current state in a single CLAUDE.md means everything becomes stale at the rate of the fastest-changing content.
MEMORY.md: What to Put in It
MEMORY.md is where most of the value of a persistent memory system lives. A useful MEMORY.md contains:
# Project Memory
Last updated: [date]
## Architecture
### Data Layer
- PostgreSQL via Prisma ORM
- Migrations in prisma/migrations/ — run with: npx prisma migrate dev
- We do NOT use Prisma's relation queries across service boundaries
(service-to-service calls use the HTTP API, not shared DB access)
### Auth
- JWT tokens, refreshed every 15 minutes
- Stored in httpOnly cookies (not localStorage)
- Auth middleware is in src/middleware/auth.ts
- Admin routes require role: "admin" in the token payload
### Key Design Decisions
- Chose Next.js App Router over Pages Router (April 2026): better server component support
- Using optimistic updates for all list mutations — the UX felt broken without it
- Email sending goes through Resend (not SES) — better dev experience
## Known Issues (Do Not "Fix")
- TypeScript error in src/lib/legacy-import.ts: intentional, suppressed with @ts-ignore
Reason: third-party lib has wrong types, upstream fix pending
- The `products.sync()` function appears to have a race condition in tests
— it's a test artifact, not a real bug. Do not refactor.
## Recently Changed (Last 30 Days)
- April 2026: Migrated payment processing to Stripe's new Payment Element
- April 2026: Added rate limiting to all public API endpoints (10 req/min)
- March 2026: Replaced react-query with SWR for client-side data fetching
## Active Work
- PR in review: Add multi-tenant support (#234)
- In progress: Notification system (branch: feature/notifications)
- Blocked: Email templates waiting on design review
The “Known Issues” section is particularly important. Without it, Claude will try to fix intentional oddities every session, wasting time on things that are not bugs.
CONTEXT.md: The Session Handoff Pattern
The session handoff pattern is the most underused technique in Claude Code memory management. At the end of each work session, ask Claude to update a CONTEXT.md file:
Update CONTEXT.md with:
1. What we completed today (be specific: function names, file paths)
2. What was left unfinished and why
3. Any decisions we made that aren't captured in MEMORY.md yet
4. What the next session should start with
The result looks like this:
# Session Context
Last session: April 11, 2026
## Completed
- Implemented createNotification() in src/services/notifications.ts
- Added notification_events table (migration: 20260411_add_notifications)
- Unit tests passing for notification service (15 tests)
- Wired up real-time notification count in the header component
## Open / In Progress
- Email delivery for notifications: service created, not wired to actual sends yet
→ Next step: integrate with Resend in src/lib/email.ts
- The notification preferences UI is a placeholder
→ Waiting for design spec from Figma
## Decisions Made
- Chose polling (5-second interval) over WebSockets for notification count updates
Reason: WebSockets add deployment complexity; polling is sufficient for this use case
→ Added to MEMORY.md
## Next Session: Start Here
1. Wire notification email sending through Resend (src/lib/email.ts)
2. Then: build the notification preferences page (design in Figma: [link])
3. Low priority: add notification read/unread batch update endpoint
When you start the next session, include CONTEXT.md in your first message:
Read CONTEXT.md, then let's continue with the notification work.
We're starting with wiring the email sending.
This eliminates the “re-explain what we were doing” overhead at every session start.
Auto Memory: Curation Strategy
Auto Memory accumulates without deliberate management. Without curation, you end up with hundreds of notes spanning two years of project history, mixing current information with outdated observations.
A practical curation approach:
Monthly review
Once a month, scan the memory directory (~/.claude/projects/<project-hash>/memory/). Look for:
- Notes that contradict your current MEMORY.md (they are outdated)
- Notes about patterns or dependencies you have removed
- Duplicate notes about the same topic
Delete outdated notes. Auto Memory works better when it is accurate and small than when it is comprehensive and stale.
Promote important notes to MEMORY.md
When Auto Memory captures something genuinely important — a learned preference, a discovered architectural constraint — move it into MEMORY.md where you control the format and it is clearly visible. Then delete the Auto Memory version to avoid duplication.
What to let Auto Memory handle
Auto Memory is best for capturing behavioral preferences Claude learns through corrections:
- “User prefers early returns over nested conditions”
- “User always wants TypeScript strict mode”
- “This project uses named exports only”
These are granular enough that writing them manually in CLAUDE.md would be tedious, but useful enough that losing them between sessions has real cost.
Team vs. Solo Developer Patterns
Memory management needs differ significantly between teams and individual developers.
Solo developer setup
For solo developers, a simple setup works well:
CLAUDE.md → your stable preferences + project rules
MEMORY.md → project knowledge + architecture state
CONTEXT.md → per-session handoffs (maintained by Claude)
Auto Memory → learned preferences (curated monthly)
Update CONTEXT.md at the end of every session. Review MEMORY.md when major architectural changes happen. Prune Auto Memory once a month.
Team setup
For teams, the main challenge is that CLAUDE.md and MEMORY.md are in the repository, so they need to reflect team conventions rather than individual preferences.
Separate individual preferences from shared ones:
~/.claude/CLAUDE.md → personal preferences (not in repo)
./CLAUDE.md → team conventions (in repo, reviewed in PRs)
./MEMORY.md → project knowledge (in repo, maintained by team)
The rule: anything about how you prefer to work goes in ~/.claude/CLAUDE.md. Anything about how the project works goes in ./MEMORY.md. Anything about how the team codes goes in ./CLAUDE.md.
For CONTEXT.md in team settings, consider per-developer session logs rather than a shared file:
.claude/sessions/ (gitignored)
alice/CONTEXT.md
bob/CONTEXT.md
This keeps session state out of the main repo history while still being persistent for each developer.
Keeping Memory Accurate Over Time
The failure mode for most memory systems is drift: the memory describes how the project was, not how it is. Three practices prevent drift:
Update at change time, not review time. When you make a significant architectural decision, update MEMORY.md immediately. Do not wait for a quarterly review. The decision is fresh in your head now and stale six weeks later.
Audit on project transitions. Before starting a new major feature or after a significant refactor, read MEMORY.md and update anything that is no longer accurate. A 15-minute review at a transition point is cheaper than correcting Claude’s misunderstandings throughout the project.
Let Claude flag inconsistencies. Occasionally ask Claude to review MEMORY.md against the actual codebase:
Review MEMORY.md and flag anything that appears to be outdated or inconsistent
with what you can observe in the current codebase. List what should be updated
but don't change anything yet.
This surfaces drift you have missed. You can then update the flagged sections.
Sample Starter Templates
MEMORY.md starter
# Project Memory
Last updated: [date]
## Architecture
[Describe your main architectural patterns, tech choices, and why]
## Key Decisions
[Major decisions with dates and rationale — why X instead of Y]
## Known Issues (Do Not Fix)
[Intentional quirks, suppressed errors, pending upstream fixes]
## Recently Changed
[Last 4–6 weeks of significant changes]
## Active Work
[What's in progress, what's blocked, what's waiting on external input]
CONTEXT.md starter
# Session Context
Last session: [date]
## Completed
[What was finished this session — be specific with file paths and function names]
## Open / In Progress
[What was started but not finished, and what the next step is]
## Decisions Made
[Anything decided this session that should eventually go into MEMORY.md]
## Next Session: Start Here
[The one thing to pick up at the top of the next session]
For the conceptual overview of Claude Code’s memory layers, see our memory persistence guide. For token optimization strategies that complement a multi-file memory setup, see our CLAUDE.md token budget guide. Browse real CLAUDE.md and MEMORY.md examples in our gallery.