Skip to content

Claude.md vs Memory Files: What's the Difference and When to Use Each

The Problem

I was optimizing my claude.md file obsessively, cramming every project detail, coding convention, and recent decision into it. Every time I read about context compaction, I panicked—what if Claude loses critical information during compression?

Then I discovered I was solving the wrong problem entirely.

The real issue wasn’t my claude.md optimization. It was that I was using the wrong tool for dynamic context. Claude Code has multiple context mechanisms, and I was conflating them, duplicating content across files, and wasting effort on the wrong optimization.

What I Discovered

After digging through Reddit discussions and community threads, I found I wasn’t alone in my confusion:

“I still don’t completely understand the difference between claude.md and memory. I am very paranoid about having an ultra-optimized claude.md file since its what it reads every time compactation occurs.” — r/ClaudeAI user

The confusion stems from Claude Code offering multiple overlapping mechanisms without clear documentation on their distinct purposes:

  1. claude.md — Project-level configuration
  2. Memory files — Session-specific context
  3. Rules — Behavioral instructions
  4. Skills — Reusable task templates

Each serves a different role, but when you’re trying to manage context efficiently, these distinctions blur. Let me break down what each actually does.

The Solution: Understanding Each Mechanism

claude.md: Your Project’s Constitution

Think of claude.md as your project’s constitution—static rules that define how the codebase operates. It’s read at session start and during compaction, making it ideal for information that doesn’t change frequently.

What goes here:

  • Tech stack declarations (React 18, TypeScript, PostgreSQL)
  • Coding conventions (functional components, colocated tests)
  • Project-specific patterns (API response format, error handling)
  • Static architectural decisions

The key insight: claude.md is configuration, not conversation. It shouldn’t contain current state, recent bugs, or session-specific information.

CLAUDE.md - Static Configuration
## Project: E-commerce Platform
### Tech Stack
- Frontend: React 18, TypeScript
- Backend: Node.js, Express
- Database: PostgreSQL
- Testing: Jest, React Testing Library
### Coding Conventions
- Use functional components
- Test files next to source: Component.test.tsx
- API responses: { success, data?, error? }
### Rules
- Always handle errors explicitly
- No console.log in production code
- Use Zod for input validation

Memory Files: Your Session’s Working Memory

Memory files are where dynamic, evolving context lives. This is where Claude tracks:

  • What you’re currently working on
  • Decisions made during the session
  • Gotchas discovered along the way
  • Known issues and their status

Critical limitation: Memory files are capped at approximately 200 lines. Content beyond this limit isn’t read, so efficiency matters.

MEMORY.md - Dynamic Context
## Current Session
- Building checkout flow
- Stripe integration 80% complete
## Recent Decisions
- 2026-03-12: Use webhooks for payment status
- 2026-03-11: Cache cart in Redis
## Known Issues
- Payment timeout on slow networks (investigating)
- Cart sync race condition (fixed in #234)
## Gotchas
- Stripe webhook needs raw body
- Redis cache keys need TTL

The difference is stark: claude.md says how we build, memory files say what we’re building right now.

Rules and Skills: Specialized Tools

Two other mechanisms fill specific niches:

Rules — Behavioral instructions that apply globally or to specific contexts. Think of these as policies Claude should always follow.

.claude/rules/coding-style.md
# Coding Style
## Immutability (CRITICAL)
ALWAYS create new objects, NEVER mutate existing ones.
## File Organization
MANY SMALL FILES > FEW LARGE FILES
- 200-400 lines typical, 800 max

Skills — Reusable task templates for common workflows. These are like macros for complex operations.

.claude/skills/review-pr.md
---
description: Review a GitHub pull request
---
Review PR #$ARGUMENTS:
1. Fetch PR details with gh pr view
2. Analyze code changes
3. Check for security issues
4. Provide feedback

When to Use Each: A Decision Matrix

Here’s the decision framework I now use:

Use CaseMechanismWhy
Tech stack choicesclaude.mdStatic, rarely changes
Coding conventionsclaude.mdRules that apply to all code
Current task contextMemory filesChanges frequently
Architectural decisionsMemory filesDated, evolving
”Always do X” policiesRulesBehavioral, not contextual
Repeated workflowsSkillsTemplate-based execution
Discovered gotchasMemory filesSession-specific learnings
Project structureclaude.mdFoundational knowledge

Common Mistakes I Made (And How to Fix Them)

Mistake 1: Dynamic State in claude.md

What I did wrong:

WRONG: Dynamic state in claude.md
## Current Work
- Fixing authentication bug in login flow
- Need to remember Stripe key location: .env.stripe
## Recent Changes
- Added rate limiting (2026-03-11)
- Fixed cart sync issue (2026-03-10)

Why it’s wrong: This information becomes stale quickly and clutters the configuration file.

The fix: Move dynamic content to memory files. claude.md should be mostly static.

Mistake 2: Letting Memory Files Grow Unbounded

What I did wrong:

My memory file hit 400 lines of detailed session notes, thinking more context was better.

Why it’s wrong: Memory files have a ~200 line limit. Content beyond this is ignored.

The fix: Keep memory concise. Archive old decisions. Focus on what’s relevant now.

RIGHT: Concise memory
## Current Session
- Refactoring payment module
## Active Decisions
- 2026-03-12: Stripe over PayPal (simpler API)
## Open Issues
- Webhook timeout (investigating)
## Key Gotchas
- Stripe needs raw body for signature verification

Mistake 3: Duplicating Across Mechanisms

What I did wrong:

I had “Use TypeScript strict mode” in claude.md, rules/coding-style.md, AND my memory file.

Why it’s wrong: Duplication wastes context budget and creates maintenance burden.

The fix: Each piece of information should live in exactly one place. Static rules in claude.md or rules files. Dynamic state in memory.

Mistake 4: Not Updating Memory Before Compaction

What I did wrong:

I let sessions run long without updating memory, then compaction would happen and Claude would lose context about what we were doing.

The fix: Periodically update memory with current state, especially before natural compaction points (end of major tasks, before context limits).

The Context Hierarchy

Understanding how Claude reads these files helps explain why the distinction matters:

Claude Code Context Reading Order
┌─────────────────────────────────────────────┐
│ 1. CLAUDE.md (project root) │
│ Read at: Session start, compaction │
│ Purpose: Static project configuration │
├─────────────────────────────────────────────┤
│ 2. Rules (.claude/rules/*.md) │
│ Read at: Session start, relevant context │
│ Purpose: Behavioral instructions │
├─────────────────────────────────────────────┤
│ 3. Skills (.claude/skills/*.md) │
│ Read at: Skill invocation │
│ Purpose: Task templates │
├─────────────────────────────────────────────┤
│ 4. Memory files │
│ Read at: Every context window │
│ Purpose: Dynamic session state │
│ Limit: ~200 lines │
└─────────────────────────────────────────────┘

Notice that memory files are read most frequently but have the strictest size limit. This reinforces the need for concise, high-value content in memory files.

Practical Workflow

Here’s the workflow I now follow:

At project start:

  1. Create claude.md with tech stack, conventions, and static rules
  2. Set up rules/ for behavioral policies
  3. Create skills/ for common workflows

During development:

  1. Keep memory updated with current task and recent decisions
  2. Prune old entries when approaching 150 lines (safe margin)
  3. Move stable decisions to project docs, keep evolving ones in memory

Before compaction:

  1. Ensure current state is captured in memory
  2. Remove resolved issues
  3. Update decision log with latest choices

Summary

The confusion between claude.md and memory files stems from treating them as competing solutions rather than complementary tools:

  • claude.md is your project’s constitution—static configuration read at session start and compaction
  • Memory files are your working notes—dynamic context read continuously but capped at ~200 lines
  • Rules define behavior policies
  • Skills provide reusable task templates

The key principle: claude.md is for what doesn’t change; memory is for what does. Put static project rules in claude.md, dynamic session context in memory, and stop duplicating between them.

Once I understood this distinction, my context management became clearer, and I stopped wasting time optimizing the wrong files.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments