Why Does Claude Code Produce Bad Output Before Hitting the Context Limit?
The Problem
I was deep in a coding session with Claude Code. Everything was going smoothly until it wasn’t.
Claude started forgetting instructions I’d given earlier. It repeated the same code patterns. It lost track of which files it had already modified. The output became generic, missing context I knew it had.
I checked my context usage: only 50,000 tokens. Claude Opus has a 200,000 token limit. I wasn’t even close to hitting it.
So why was the quality degrading?
The Hidden Degradation Problem
The answer surprised me: Claude’s quality starts slipping at 20-40% of context capacity. Not at 100%. Not at 80%. At 20-40%.
Context Window: 200,000 tokens (Claude Opus)
Quality Degradation Zones: 0-20% → Peak performance 20-40% → Quality starts slipping 40%+ → Significant degradation
Why 40,000-80,000 tokens and not 200,000? → Attention dilution, not token exhaustionThe issue isn’t running out of space. It’s attention dilution.
What Is Attention Dilution?
Large language models use an attention mechanism to determine which parts of the context are relevant. When context is small, attention focuses clearly. As context grows, attention spreads thinner.
Small Context (10,000 tokens): [Query] → Attention focuses on relevant tokens → Quality output
Large Context (80,000 tokens): [Query] → Attention distributed across many tokens → Diluted focus → Degraded outputThink of it like a spotlight. A small stage is fully illuminated. A massive stadium has the same spotlight, but now the light is spread thin. Everything is dimmer.
I noticed this pattern:
Symptoms of Attention Dilution:1. Forgetting earlier instructions2. Repeating the same code or explanations3. Losing track of file context4. Making inconsistent edits across files5. Producing generic output that ignores specifics6. Missing edge cases it would normally catchCompaction Doesn’t Fix This
Here’s what confused me: Claude Code has a compaction feature. It summarizes old context to make room. Shouldn’t that solve the problem?
Not always.
What I expected: Long context → Compaction → Clean slate → Good output
What actually happened: Long context → Degraded state → Compaction → Still degraded outputThe issue: if the model is already confused before compaction, the summarized context can preserve that confusion. The mental model is corrupted, and compaction just compresses the corruption.
The Solutions
Through trial and error, I found four strategies that work.
Strategy 1: Scope Conversations Narrowly
I used to have one long conversation for an entire feature. Now I start fresh conversations for each sub-task.
Before (BAD): Conversation 1: "Build the entire authentication system" → Login, signup, password reset, OAuth, 2FA → Context grows to 80,000+ tokens → Quality degrades
After (GOOD): Conversation 1: "Set up basic email/password authentication" Conversation 2: "Add password reset flow" Conversation 3: "Integrate OAuth providers" Conversation 4: "Implement 2FA" → Each stays under 40,000 tokens → Quality stays highThis was the single biggest improvement. Smaller conversations mean clearer attention.
Strategy 2: Use External Memory
Claude doesn’t need to remember everything in conversation context. I have it write important information to files.
Instead of: [Long conversation context with all decisions and progress]
I do: [Short conversation context] + project-context.md file
Claude reads the file when needed, not every message.Example project-context.md that Claude creates and maintains:
## Current TaskImplementing user authentication
## Files Modified- src/auth/login.ts- src/auth/signup.ts- src/middleware/auth.ts
## Key Decisions- Using bcrypt for password hashing- JWT with 7-day expiry- Redis for session storage
## Next Steps- Add password validation- Implement rate limiting- Write integration testsWhen starting a new conversation, I just point Claude to this file.
Strategy 3: The Copy-Paste Reset
When I notice degradation mid-conversation, I use this workflow:
Step 1: Copy essential context - Current file paths - Active task description - Key decisions made - Recent errors encountered
Step 2: Run /compact - Summarizes current state
Step 3: Run /clear - Resets context completely
Step 4: Paste only what matters - Just the essentials - Leave behind the noiseThis takes 30 seconds and often restores quality immediately.
Strategy 4: Use /clear Proactively
Don’t wait for degradation. I clear context between distinct tasks.
User: Implement user login featureClaude: [implements login]User: /clearUser: Now implement password resetClaude: [implements password reset - fresh context]The /clear command is my friend. I use it liberally.
A Detection Workflow
Here’s the workflow I follow to catch degradation early:
Start Conversation │ ▼ Working... │ ▼ ┌─────────────────┐ │ Token Usage? │ └────────┬────────┘ │ ┌─────┴─────┐ │ │ < 20% 20-40% │ │ ▼ ▼ Continue Monitor │ ▼ ┌─────────────┐ │ Quality OK? │ └──────┬──────┘ │ ┌─────┴─────┐ │ │ Yes No │ │ ▼ ▼ Continue Copy-Paste Reset │ ▼ ContinueI check context usage periodically (Claude Code shows this in the UI). If I’m past 40,000 tokens and quality drops, I reset.
Why This Matters
Understanding context degradation changed how I work:
Before, I thought Claude “broke” randomly. I’d waste time debugging the AI instead of debugging my approach.
Now, I recognize the pattern. Quality drop + high context = time to reset.
Time spent debugging "broken" AI output: Before: 2+ hours per session After: 15 minutes (reset + continue)
Cost efficiency: Degraded output → more iterations → more tokens wasted Clean context → fewer iterations → tokens well spentCommon Mistakes I Made
Mistake 1: One Conversation for Everything
I treated conversations like documents. Keep everything in one place for reference.
Wrong. Conversations are working memory. They should be small and focused.
Mistake 2: Thinking Compaction Was Enough
I saw the compaction feature and assumed it solved context issues.
Compaction helps, but it doesn’t fix the underlying attention dilution. Sometimes you need a full reset.
Mistake 3: Never Using /clear
I thought clearing context meant losing work.
Actually, the work is in the files. The conversation is just the path to get there. Clearing context doesn’t clear files.
Mistake 4: Keeping History “Just in Case”
I kept long conversation history because I might need to reference something.
Now I have Claude write important decisions to files. The conversation can be cleared; the decisions remain.
The Statelessness Reality
Here’s a mindset shift that helped me:
Claude is stateless. Every conversation starts from nothing except what I explicitly give it.
This means:
- Long conversations don’t give Claude “memory”
- They give Claude “noise”
- External files are the real memory
/clearis not losing work, it’s reducing noise
When to Reset
Reset when: ☑ Context usage exceeds 80,000 tokens ☑ Output quality noticeably drops ☑ Claude forgets recent instructions ☑ Repetition increases ☑ Switching to a new feature/area
Don't reset when: ☐ In the middle of a complex multi-file edit ☐ Context is under 40,000 tokens and quality is good ☐ Claude is actively debugging an issueSummary
Claude Code quality degrades at 20-40% context usage due to attention dilution, not token exhaustion. The model’s attention mechanism becomes less effective at focusing on relevant information when too much context accumulates.
The fixes:
- Scope conversations narrowly - one task per conversation
- Use external memory - write important context to files
- Copy-paste reset - copy essentials,
/compact,/clear, paste back - Use
/clearproactively - don’t wait for degradation
The key insight: context window is a spotlight, not a storage container. More context doesn’t mean better memory; it means dimmer focus.
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