Thirty Messages In, Your Instructions Have Vanished
You've been working with Claude for a while — refining a document, iterating on code, building out an idea — when you notice something's off. The formatting rules you established at the start? Gone. The data you pasted twenty messages ago? Claude acts like it never existed.
This isn't a bug. It's a fundamental constraint of how large language models process conversations, and once you understand the mechanics, there are concrete strategies to work around it.
How Context Windows Actually Work (And Where They Break Down)
Claude doesn't "remember" your conversation the way humans remember a discussion from earlier today. Every time you send a message, the entire conversation history — every message you've sent and every response Claude has given — gets packaged into a single text block and fed to the model. This text block has a hard limit called the context window. For Claude Sonnet 4.6, that's roughly 200K tokens, which translates to approximately 150,000 words of English text.
When the conversation exceeds this limit, older messages get trimmed from the beginning. Claude literally cannot see what's been cut.
But here's what catches most people off guard: performance degrades well before you hit the limit. In practice, once you've consumed 60–70% of the context window, Claude's fidelity to early instructions starts to slip. This happens because the attention mechanism — the part of the model that decides which information matters most — naturally gives more weight to recent content. Your carefully crafted instructions from message #3 are competing for attention against fifty subsequent exchanges, and they're losing.
Diagnosing the Problem: Is Claude Forgetting or Just Not Seeing?
Before jumping to solutions, it's worth identifying which of three distinct failure modes you're hitting.
Pattern 1: Context overflow. The conversation is simply too long, and your early messages have been physically removed. In Claude's web app, long conversations are automatically compressed. With the API, token management is entirely your responsibility.
Pattern 2: Instruction dilution. Your instructions are technically still in the context, but they're buried under dozens of exchanges. A single-line rule written in message #2 is easy for the model to overlook when it's processing hundreds of lines of subsequent dialogue.
Pattern 3: Conflicting instructions. You've inadvertently overridden earlier guidance. Maybe you said "always use bullet points" in message #5, then wrote "format this as prose" in message #30. Claude tends to favor the most recent instruction, which may not be what you intended.
A quick diagnostic: ask Claude to "summarize the rules I established at the beginning of this conversation." If it can accurately recite them, you're dealing with Pattern 2 or 3. If it can't, you've hit Pattern 1.
Fix 1: Move Persistent Instructions to System Prompts or Projects
Instructions buried in conversation history are fragile. System prompts (the system parameter in the API) and Claude Projects' custom instructions sit in a privileged position — they're injected at the highest priority every single time.
# Place durable rules in the system prompt, not in chat messages
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6-20260312",
max_tokens=1024,
system=(
"You are a technical writer. Follow these rules in every response:\n"
"1. Use ## headings only — never ### or deeper\n"
"2. Every code example must include comments\n"
"3. Keep each response under 300 words"
),
messages=[
{"role": "user", "content": "Explain Python list comprehensions"}
]
)
print(response.content[0].text)
# → Response formatted according to system prompt rulesIf you're using Claude's web interface, Projects are the easiest way to achieve this. Whatever you write in a project's custom instructions applies automatically to every conversation within that project — no need to repeat yourself.
Fix 2: Split Conversations by Phase
This is the simplest and most effective technique: stop trying to do everything in one thread. When the topic or task phase changes, start a new conversation.
If you're doing a code review, split it into three conversations — design discussion, implementation review, test generation. Carry forward a brief summary of conclusions from each phase.
From my experience, 20–30 exchanges is a reasonable ceiling for a single conversation. If you're pasting large blocks of code or data, cut that number to 10–15. The few seconds it takes to start a fresh chat and paste a summary will save you from the frustration of Claude "forgetting" critical instructions.
Fix 3: Remind Claude Mid-Conversation
When you can't avoid a long conversation, reinject your key rules every 10–15 exchanges. The trick is to combine the reminder with your next request rather than sending it as a standalone message.
[After about 10 exchanges]
User: Before we continue, let me restate the ground rules for this session:
- Output format: Markdown with ## headings only
- Word limit: 300 words per response
- All code examples must include comments
With those in mind, here's the next task: [your actual request]
Bundling the reminder with a task means Claude processes both together, which significantly improves adherence compared to sending the rules in isolation.
Fix 4: Monitor Token Usage and Auto-Reset (API Users)
If you're building with the API, you have access to the usage field in every response. Set up automatic conversation resets before quality degrades.
# Track token consumption and auto-reset at a threshold
MAX_CONTEXT_RATIO = 0.6 # Reset at 60% capacity
MAX_TOKENS = 200000 # Claude Sonnet 4.6 context limit
THRESHOLD = int(MAX_TOKENS * MAX_CONTEXT_RATIO)
conversation_history = []
def chat(user_message: str) -> str:
conversation_history.append({"role": "user", "content": user_message})
response = client.messages.create(
model="claude-sonnet-4-6-20260312",
max_tokens=1024,
system="Your system prompt here",
messages=conversation_history
)
reply = response.content[0].text
conversation_history.append({"role": "assistant", "content": reply})
# Check if we're approaching the danger zone
total_tokens = response.usage.input_tokens + response.usage.output_tokens
if total_tokens > THRESHOLD:
summary = summarize_conversation(conversation_history)
conversation_history.clear()
conversation_history.append({
"role": "user",
"content": f"Summary of our previous conversation: {summary}\n\nLet's continue."
})
print(f"⚠ Context at {total_tokens}/{MAX_TOKENS} tokens — conversation reset")
return replyPay attention to input_tokens specifically — that's what actually fills up your context window. The output_tokens count reflects the response itself. The 60% threshold is conservative; adjust based on how instruction-sensitive your use case is. If you're pairing this with Prompt Caching, reset costs become negligible since frequently-used content stays cached. See our Prompt Caching cost optimization guide for details.
Fix 5: Use CLAUDE.md for Claude Code Projects
Claude Code users have a unique advantage: the CLAUDE.md file in your project root is automatically loaded into every session's context. Write your project rules there once, and they persist across sessions without any manual effort.
# Practical CLAUDE.md example
## Coding Standards
- TypeScript strict mode required
- All errors must be caught with try-catch
- Remove console.log after debugging
## Project Structure
- src/api/ — API routes (Hono.js)
- src/lib/ — Shared utilities
- src/components/ — React components
## Hard Rules
- Never use the `any` type
- Never delete existing testsThis solves the cross-session consistency problem at its root. For deeper patterns on structuring CLAUDE.md effectively, see our system prompt design patterns guide.
Your Next Step: Diagnose First
Next time Claude seems to have lost the plot, resist the urge to immediately start over. Instead, ask: "Can you summarize what I asked you to do at the beginning of this conversation?" The answer will tell you exactly which fix to apply.
Just like debugging code, accurately identifying the problem is the fastest path to a solution.