Claude Code Session Compaction in 2026: How Context Summarization Works and What Your Agent Forgets
How Claude Code's context summarization works under the hood, what gets lost during compaction, and how to design session state that survives automatic truncation in production agents.
Most Claude Code session failures stem from a single misunderstanding: developers treat the 200K context window as infinite storage when it is actually a rolling buffer with aggressive summarization. The agent hits the limit mid-conversation, compacts its history into a lossy summary, and continues executing with critical context missing. The failure mode here is subtle but expensive: your agent produces syntactically correct code that violates constraints it learned 50 messages ago but forgot during compaction.
When Claude Code reaches approximately 160K tokens (80% of the 200K window), the runtime automatically triggers context summarization. The system preserves the most recent exchanges and system prompt, condenses the middle conversation into a prose summary, and discards the original messages. This process happens silently. No error surfaces. The agent continues responding, but the detailed reasoning chains, rejected approaches, and discovered edge cases from earlier in the session vanish.
flowchart LR
A("session reaches 160K tokens") --> B("agent continues without warning") --> C("produces code violating earlier constraints")
style C stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
The correct approach anchors critical context outside the conversation buffer. Developers who treat Claude Code sessions as append-only logs lose state during compaction. Engineers who externalize constraints, decisions, and open tasks into persistent artifacts maintain continuity across compaction boundaries. The difference shows up in production: one pattern produces agents that drift after long conversations, the other maintains coherence through unlimited exchanges.
flowchart LR
A("session reaches 160K tokens") --> B("compaction preserves externalized state") --> C("agent maintains constraint adherence")
style C stroke:#34d399,fill:#0b3b2e,color:#d1fae5
Key Takeaways
- Claude Code auto-compacts at ~160K tokens (80% of 200K window), summarizing middle conversation into prose and discarding original messages without warning.
- Compaction preserves system prompt, recent exchanges, and explicit artifacts; ephemeral reasoning chains, rejected approaches, and discovered edge cases vanish.
- Externalizing constraints into persistent artifacts (decision logs, constraint manifests) maintains continuity across compaction boundaries.
- Manual compaction gives control over what survives; forcing early summaries with explicit retention rules prevents silent context loss.
- Token discipline (concise system prompts, artifact-based state, pruning dead branches) delays or eliminates compaction in most sessions.
How Context Summarization Actually Works Under the Hood
Context summarization operates as a three-phase pipeline: retention selection, summary generation, and buffer reconstruction. When the session token count crosses the compaction threshold, the runtime partitions the conversation history into three segments. The system prompt and configuration directives occupy the first segment and survive untouched. The most recent N exchanges (typically 10-15 turns) occupy the third segment and also survive intact. The middle segment, containing the bulk of the conversation, feeds into the summarization model.
The summarization model produces a condensed prose version of the middle segment. This summary aims to preserve factual outcomes: what files were modified, what errors were resolved, what dependencies were added. The summary does not preserve the reasoning process that led to those outcomes. A conversation where the agent tried four approaches before finding the correct one compacts into "implemented authentication using JWT" with no record of the three rejected strategies or why they failed.
flowchart TD
A("session reaches 160K tokens") --> B("partition into three segments")
B --> C("system prompt segment")
B --> D("middle conversation segment")
B --> E("recent N exchanges")
C --> F("preserved unchanged")
E --> F
D --> G("feed to summarization model")
G --> H("generate prose summary")
H --> I("discard original messages")
I --> J("reconstruct buffer with summary")
style D stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style I stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
The reconstructed buffer contains: original system prompt, generated summary, recent exchanges. The agent continues from this state with no indication that compaction occurred. Total token count drops significantly, allowing the conversation to continue. The implication here is that the agent's "memory" of earlier conversation becomes a high-level narrative rather than a detailed transcript.
Summarization quality varies with conversation structure. Linear conversations where each exchange builds on the previous one produce coherent summaries. Branching conversations where the agent explores multiple parallel tracks produce summaries that collapse those branches into a single narrative, losing the distinctions between approaches. Conversations with explicit artifact creation (decision documents, constraint lists) produce summaries that reference those artifacts, effectively externalizing the critical state.
The runtime uses a smaller model for summarization than for the main conversation. This creates a semantic compression bottleneck: subtle distinctions the main model understood may not survive the summarization model's interpretation. A constraint phrased as "prefer functional patterns except in performance-critical paths" might summarize to "use functional patterns" with the exception clause lost.
What Your Agent Forgets During Compaction (And What Survives)
Compaction destroys detailed reasoning chains first. When the agent walks through a complex type inference problem, explains why approach A fails, tries approach B, discovers a TypeScript limitation, and finally succeeds with approach C, the summary collapses this to "resolved type inference issue." The exploration process vanishes. The agent cannot reference "the problem we encountered with approach B" in later conversation because approach B no longer exists in context.
Rejected approaches disappear entirely. If the agent proposed using Redis for caching, the team rejected it due to operational constraints, and the conversation moved to an in-memory solution, compaction summarizes "implemented in-memory caching" with no record of the Redis discussion. Later in the session, if a new problem surfaces that Redis would solve, the agent may propose Redis again, unaware of the earlier rejection.
flowchart TD
A("pre-compaction context") --> B("detailed reasoning chains")
A --> C("rejected approaches with rationale")
A --> D("edge cases discovered")
A --> E("constraint interpretations")
A --> F("factual outcomes")
B --> G("collapses to outcome only")
C --> H("vanishes completely")
D --> I("survives if referenced in outcome")
E --> J("survives if externalized")
F --> K("preserved in summary")
style H stroke:#ef4444,fill:#450a0a,color:#fca5a5
style G stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
style K stroke:#34d399,fill:#0b3b2e,color:#d1fae5
Edge cases discovered during implementation survive only if they resulted in code changes. A conversation where the agent identifies "null handling breaks for empty arrays" and adds a guard clause will summarize "added null handling." But if the agent identifies the edge case, determines it cannot occur in the current architecture, and documents this conclusion in a comment without changing logic, the summary may not mention it. Later refactoring might reintroduce the vulnerability because the agent forgot the analysis.
Constraint interpretations often get lost. When a human says "keep bundles under 200KB" and the agent asks "do you mean 200KB gzipped or uncompressed?" and the human clarifies "gzipped", that clarification exists as an exchange in the middle segment. After compaction, the summary says "optimized bundle size" with no record of the gzip requirement. The agent reverts to its default assumption (usually uncompressed) in subsequent work.
Explicit artifacts survive compaction because the agent stores them as distinct context items rather than conversation history. A decision document created with "create a file called DECISIONS.md documenting our approach" persists across compaction. The agent can reference and update this file in later exchanges. This distinction is critical: ephemeral conversation compacts away, named artifacts persist.
System prompt directives survive untouched. If your system prompt includes "always use strict null checks" that directive remains active after compaction. Configuration passed as conversation context ("for this session, assume PostgreSQL 15") may or may not survive depending on where it appears in the conversation timeline.
Recent exchanges survive intact. The last 10-15 turns remain in full detail, creating a sliding window of recent context. This means the agent maintains strong coherence for immediate follow-up work but loses long-term context. A feature implemented 100 messages ago exists only as a summary, while work from the last 10 messages remains detailed.
Reading Compaction Events: Debugging What Got Summarized Away
Claude Code emits compaction events through its streaming API when summarization occurs. These events appear in the conversation metadata stream with type context.compaction. The event payload includes the original token count, post-compaction token count, and the number of messages summarized. Monitoring these events reveals when compaction happens and how much context collapses.
interface CompactionEvent {
type: "context.compaction";
timestamp: string;
preCompactionTokens: number;
postCompactionTokens: number;
messagesSummarized: number;
summaryTokens: number;
}
function monitorCompaction(eventStream: AsyncIterable<Event>) {
for await (const event of eventStream) {
if (event.type === "context.compaction") {
console.warn(
`Compaction at ${event.timestamp}: ${event.messagesSummarized} messages ` +
`(${event.preCompactionTokens} → ${event.postCompactionTokens} tokens)`
);
const compressionRatio =
event.preCompactionTokens / event.postCompactionTokens;
if (compressionRatio > 3.0) {
console.error(
"High compression ratio detected. Significant context loss likely."
);
}
}
}
}The compression ratio indicates summarization aggressiveness. A ratio above 3.0 means the summary is less than one-third the size of the original content, suggesting substantial information loss. Ratios below 2.0 indicate gentler summarization where more detail survives.
Debugging context loss requires comparing the generated summary against the original conversation. The API does not expose the summary text directly, but developers can reconstruct it by examining the assistant's responses immediately after compaction. The first response following a compaction event often includes phrases like "as discussed earlier" or "building on our previous implementation" that reference summarized content. These references reveal what the agent believes it remembers.
interface ConversationMessage {
role: "user" | "assistant";
content: string;
tokenCount: number;
timestamp: string;
}
interface ContextSnapshot {
messages: ConversationMessage[];
totalTokens: number;
compactionHistory: CompactionEvent[];
}
function analyzeContextAfterCompaction(
snapshot: ContextSnapshot,
lastCompaction: CompactionEvent
): { preserved: string[]; likely_lost: string[] } {
const recentMessages = snapshot.messages
.filter(m => new Date(m.timestamp) > new Date(lastCompaction.timestamp))
.slice(-15);
const preserved = recentMessages.map(m => m.content);
const oldMessages = snapshot.messages
.filter(m => new Date(m.timestamp) < new Date(lastCompaction.timestamp));
const likely_lost = oldMessages
.filter(m => m.content.includes("rejected") || m.content.includes("alternative"))
.map(m => m.content);
return { preserved, likely_lost };
}This analysis identifies messages containing rejected approaches or alternatives that fell into the summarized segment. These represent the highest-risk context losses because they contain negative information (what not to do) that summaries rarely preserve.
Production systems should log compaction events alongside other operational metrics. A sudden increase in compaction frequency indicates either longer conversations or more verbose agent responses. Both patterns suggest architectural problems: the first means session design encourages long-running conversations instead of bounded tasks, the second means prompt engineering produces unnecessary verbosity.
Designing Session State That Survives Compaction
Session state design determines what survives compaction. Ephemeral state stored only in conversation history vanishes during summarization. Persistent state stored in external artifacts remains accessible across compaction boundaries. The architecture choice here drives long-term agent coherence.
The artifact pattern externalizes critical state into named documents the agent maintains throughout the session. A constraint manifest lists all requirements, edge cases, and architectural decisions. The agent updates this manifest as new constraints emerge. During compaction, the conversation history compresses but the manifest persists as a separate context item.
flowchart LR
A("conversation includes new constraint") --> B("agent updates CONSTRAINTS.md") --> C("compaction occurs") --> D("conversation summarized") --> E("CONSTRAINTS.md survives") --> F("agent references manifest in later work")
style B stroke:#c084fc,fill:#3b0764,color:#f3e8ff,stroke-width:4px
style E stroke:#34d399,fill:#0b3b2e,color:#d1fae5
The manifest should use structured format that the agent parses reliably. Unstructured prose produces inconsistent interpretation. A JSON or YAML structure with explicit keys ensures the agent extracts requirements correctly even after multiple updates.
// CONSTRAINTS.md structure that survives compaction
interface ConstraintManifest {
architectural: {
patterns: string[];
forbidden: string[];
};
performance: {
bundleSize: { max: string; measured: "gzipped" | "uncompressed" };
responseTime: { target: string; percentile: number };
};
dependencies: {
allowed: string[];
prohibited: string[];
rationale: Record<string, string>;
};
edgeCases: {
description: string;
handling: string;
testCoverage: boolean;
}[];
}
// Agent reads this at session start and after each update
const manifest: ConstraintManifest = {
architectural: {
patterns: ["functional composition", "immutable state"],
forbidden: ["class inheritance beyond two levels", "global mutable state"]
},
performance: {
bundleSize: { max: "200KB", measured: "gzipped" },
responseTime: { target: "200ms", percentile: 95 }
},
dependencies: {
allowed: ["react", "typescript", "vite"],
prohibited: ["lodash", "moment"],
rationale: {
lodash: "bundle size overhead, prefer native methods",
moment: "deprecated, use native Temporal API"
}
},
edgeCases: [
{
description: "null handling for empty arrays",
handling: "explicit guard clause returning empty array",
testCoverage: true
}
]
};Decision logs capture the reasoning behind architectural choices. When the agent evaluates multiple approaches, the decision log records each option, evaluation criteria, and final choice. This log persists across compaction, allowing the agent to reference past decisions when similar situations arise.
State snapshots provide rollback capability. At key conversation milestones (feature complete, passing tests, production ready), the agent creates a state snapshot containing current code, configuration, and context summary. If later work introduces regressions, the team can restore a snapshot and continue from that point with all context intact.
The pattern extends to test suites as executable documentation. Tests encode requirements in assertions. When compaction loses conversational context about why a particular validation exists, the test suite preserves it as failing assertions if the behavior changes. This makes tests a first-class citizen in context management, not just verification.
Token budgets limit artifact size growth. A constraint manifest that grows without bounds eventually contributes to compaction pressure. Implement periodic pruning: remove obsolete constraints, consolidate duplicate entries, archive resolved edge cases. The manifest should represent current state, not complete history.
Manual Compaction vs Auto-Compaction: When to Force a Summary
Auto-compaction triggers at 80% capacity (160K tokens) with no developer control over timing or content. The runtime decides what survives. Manual compaction gives explicit control: developers force summarization at strategic conversation boundaries and specify retention rules for the summary generation.
Auto-compaction optimizes for conversation continuity. The system prioritizes keeping the conversation flowing without interruption. This works well for exploratory sessions where context naturally evolves. It fails for sessions with critical early decisions that must persist throughout.
flowchart LR
A("session design") --> B{"compaction strategy"}
B -->|exploratory| C["auto-compaction at 160K"]
B -->|decision-heavy| D["manual compaction after key milestones"]
C --> E("conversation flows smoothly")
C --> F("early decisions may vanish")
D --> G("explicit retention control")
D --> H("requires session structure discipline")
style F stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
style G stroke:#34d399,fill:#0b3b2e,color:#d1fae5
Manual compaction fits sessions with distinct phases: requirements gathering, architecture design, implementation, testing. At each phase boundary, the agent summarizes the completed phase with explicit instructions about what to retain. The requirements phase summary preserves all constraints. The architecture phase summary preserves chosen patterns and rejected alternatives. The implementation phase summary preserves code structure and edge case handling.
The API provides a compact() method that triggers summarization immediately. The method accepts a retention policy object specifying what content categories to preserve in the summary.
interface RetentionPolicy {
preserveConstraints: boolean;
preserveRejectedApproaches: boolean;
preserveEdgeCases: boolean;
preserveDecisionRationale: boolean;
customInstructions?: string;
}
async function manualCompaction(
session: ClaudeSession,
policy: RetentionPolicy
): Promise<CompactionResult> {
const result = await session.compact({
retentionPolicy: policy,
validateSummary: true
});
if (!result.success) {
throw new Error(`Compaction failed: ${result.error}`);
}
console.log(
`Compacted ${result.messagesSummarized} messages. ` +
`Tokens: ${result.preCompactionTokens} → ${result.postCompactionTokens}`
);
return result;
}
// Force compaction after architecture phase
await manualCompaction(session, {
preserveConstraints: true,
preserveRejectedApproaches: true,
preserveEdgeCases: true,
preserveDecisionRationale: true,
customInstructions:
"Retain the rationale for choosing event sourcing over CRUD, " +
"including the PostgreSQL trigger limitation that ruled out CRUD."
});Custom instructions in the retention policy provide fine-grained control. These instructions go directly to the summarization model, allowing developers to highlight specific conversation segments for preservation. A complex type system discussion might include "preserve the explanation of why branded types solved the ID confusion problem" to ensure that reasoning survives.
Validation after manual compaction confirms the summary contains expected content. The agent performs a test query referencing a key concept from the summarized segment. If the agent cannot answer, the summary lost critical information. This triggers either a compaction retry with adjusted retention policy or a manual context injection to restore the lost information.
The tradeoff here is session structure overhead. Auto-compaction requires no session management: developers start a conversation and continue until complete. Manual compaction requires explicit phase boundaries and retention decisions. For short sessions (under 100K tokens), the overhead exceeds the benefit. For long-running agent collaborations spanning days, manual compaction prevents subtle context drift that degrades work quality.
Hybrid strategies combine both approaches. Use auto-compaction for exploratory work within a phase, force manual compaction at phase boundaries. This gives continuity during active work while ensuring phase transitions preserve critical context.
Token Discipline: Preventing Compaction Before It Happens
Token discipline delays or eliminates compaction by reducing conversation verbosity. Most sessions hit compaction not because the task requires 200K tokens but because verbose exchanges and redundant explanations consume tokens unnecessarily. Tight communication protocols keep sessions well below the compaction threshold.
System prompts drive agent verbosity. A prompt saying "explain your reasoning in detail" produces longer responses than "provide concise implementation." The difference compounds over dozens of exchanges. Teams that optimize system prompts for brevity see 40-60% token reduction without information loss.
flowchart LR
A("verbose system prompt") --> B("detailed explanations in every response") --> C("reaches 160K tokens in 30 exchanges")
D("concise system prompt") --> E("focused responses with reasoning on request") --> F("stays under 100K tokens for typical session")
style C stroke:#fbbf24,fill:#3a2f0b,color:#fef3c7
style F stroke:#34d399,fill:#0b3b2e,color:#d1fae5
The artifact pattern itself reduces token consumption. Externalizing state into persistent documents means the agent references documents instead of repeating information. A conversation without artifacts might explain the authentication flow in three different exchanges as context for different questions. With artifacts, the agent writes the flow once in AUTH_DESIGN.md and references that document in subsequent responses.
Pruning dead conversational branches prevents token waste. When the agent explores an approach that fails, developers should explicitly mark the branch dead: "We're abandoning the Redis approach. Do not reference it in future responses." This signals the agent to stop carrying that context forward, reducing tokens spent on maintaining irrelevant state.
Code examples should appear in artifacts rather than conversation. When the agent provides a code example, the human should request "put that in src/auth.ts and we'll iterate on the file" instead of continuing with code in conversation. Files consume tokens only when explicitly read, while conversation code consumes tokens for the remainder of the session.
Concise human prompts matter as much as concise agent responses. A prompt like "The button click handler needs to validate the form, check authentication, make the API call, handle errors, update UI state, and log analytics" contains the same information as "Implement the submit handler per REQUIREMENTS.md" when requirements are externalized. The second prompt saves 20+ tokens per exchange.
Response length limits prevent verbose digressions. System prompts can specify "Keep responses under 500 tokens unless asked for detail." The agent learns to provide focused answers and offer to elaborate rather than proactively explaining everything. This creates a pull model where humans request additional context only when needed.
Token counting middleware logs per-exchange token consumption, revealing verbose patterns. An exchange that consumes 2000+ tokens likely contains unnecessary explanation or repeated context. Review these exchanges to identify optimization opportunities: what could move to an artifact? What explanation was redundant? What context does the agent carry that it no longer needs?
Sessions designed around artifacts, concise prompts, and response discipline regularly complete complex tasks in 80-120K tokens. These sessions never trigger compaction. The development experience improves because humans and agents communicate efficiently rather than verbosely. The speed gain from shorter exchanges often exceeds the context management benefit.
Frequently Asked Questions
Does manual compaction improve summary quality over auto-compaction?
Manual compaction with explicit retention policies produces summaries that preserve specific conversation elements you designate. Auto-compaction uses generic summarization that optimizes for conversation continuity but may lose critical decisions or rejected approaches. For sessions with important early context, manual compaction at phase boundaries prevents silent context loss.
Can the agent detect when it has lost context during compaction?
The agent cannot intrinsically detect context loss. It processes the post-compaction state as complete and continues responding. Developers must monitor compaction events, track compression ratios, and validate that the agent maintains constraints from earlier conversation. High compression ratios (above 3.0) indicate significant information loss and warrant verification.
How do artifacts interact with the context window limit?
Artifacts count against the total context window but receive special handling during compaction. Named documents persist across summarization while conversation history compresses. A 200KB session might have 50KB in artifacts and 150KB in conversation. After compaction, artifacts remain at 50KB, conversation compresses to 30KB, leaving 120KB available for continued work.
What happens when a session exhausts the context window even after compaction?
Once compaction reduces token count below the threshold, the session can continue. If the session reaches 200K again, another compaction occurs. Eventually, with enough iterations, even aggressive summarization cannot free sufficient space. At that point, the session must end and a new session begins. Starting a new session loses all context except what was explicitly externalized to artifacts or files.
Is there a way to preserve the entire conversation history without compaction?
No. The 200K context window is a hard limit. Developers can externalize critical information to artifacts and decision logs before compaction, but the conversation transcript itself cannot exceed the limit. For scenarios requiring complete history preservation, implement conversation logging outside Claude's context system and reference that log in subsequent sessions.
Building Compaction-Aware Agents That Don't Lose Critical Context
Context summarization becomes a non-issue when session architecture acknowledges compaction as inevitable rather than treating it as a failure mode. Agents designed with explicit state management, artifact-based persistence, and token discipline operate effectively through multiple compaction cycles without coherence loss. The pattern shifts from fighting compaction to working within its constraints.
Successful agent architectures combine three elements: externalized constraints that survive compaction as artifacts, manual compaction at phase boundaries with explicit retention policies, and token discipline that keeps most sessions below compaction thresholds entirely. Together these patterns eliminate the common failure mode where agents drift after long conversations and produce work that violates earlier decisions.
The distinction between treating context as an append-only log versus treating it as a managed resource determines agent reliability over extended collaboration. Teams that implement compaction-aware patterns see consistent agent behavior across sessions lasting days or weeks. Teams that ignore compaction encounter subtle failures that surface only in production when critical edge cases or architectural constraints vanish from agent memory.
That covers the essential patterns for Claude Code context management. Apply these in production and the difference will be immediate.