OpenCode V2 Compaction Internals An analysis of OpenCode V2's compaction mechanism reveals it is a durable checkpoint-and-retry system, not a relevance-pruning tool. The system triggers compaction based on context size, not message importance, and compresses older context into a hardcoded 4,096-token summary. Media content is reduced to text metadata after compaction, and history is never deleted but old rows are no longer loaded for model requests. This document analyzes the OpenCode V2 compaction implementation. The conclusions are based on the V2/core code path in the OpenCode repository. When code, comments, and documentation disagree, this document follows the current code behavior. Primary code references: packages/core/src/session/compaction.ts packages/core/src/session/runner/llm.ts packages/core/src/session/history.ts packages/core/src/session/context-epoch.ts packages/core/src/session/runner/to-llm-message.ts packages/core/src/session/message-updater.ts packages/core/src/config/compaction.ts This document only covers the V2/core compaction path. It does not cover the V1 compatibility /compact implementation or the DCP plugin's compress tool. OpenCode V2 compaction is a durable checkpoint-and-retry mechanism, not a relevance-pruning system. It is a last-resort survival mechanism — avoid triggering it whenever possible. Avoid compaction. Once triggered, all older context is compressed into a hardcoded 4 096 -token summary. Details that do not fit are not recovered. The session survives, but its continuity depends entirely on what the summary captured. Compaction is size-triggered, not relevance-triggered. It runs when the request estimate exceeds the context threshold — regardless of how important or irrelevant the conversation is. The system has no concept of message importance. Three hardcoded limits control quality. Tool/shell output is truncated at 2 000 chars TOOL OUTPUT MAX CHARS , summary output is capped at 4 096 tokens SUMMARY OUTPUT TOKENS , and neither is configurable. Only buffer and keep.tokens are exposed in the config schema. History is never deleted, but old rows are no longer loaded. Old messages remain in durable storage. After compaction, future model requests start from the checkpoint and do not see older rows through normal provider calls. Media content is not preserved in model-visible context after compaction. Images and videos from before the checkpoint are reduced to text metadata Attached image/png: screenshot.png . The original binary data remains in durable history, but the model cannot see visual content from before the checkpoint through normal provider requests. Compaction is safe but blunt. It never deletes history, never leaves a half-compacted session, and prevents infinite retry loops. But it makes no attempt to distinguish important facts from noise when summarizing older context. Long coding-agent sessions produce long conversation histories. Tool calls, tool results, shell outputs, file reads, and multi-turn reasoning accumulate. Eventually the full provider request exceeds the model's context limit. Deleting old messages would lose durable history. Compaction solves this with a checkpoint strategy: create a new message that represents older history, then let future runner attempts use that message as a starting boundary. V2 compaction separates three layers that would otherwise be conflated: | Layer | What it is | What compaction does to it | |---|---|---| | Durable history | Full session record in SessionMessageTable | Not changed. Old rows remain. | | Active history | The slice of messages loaded for a provider attempt | Shortened. Future loads start from the latest type: "compaction" checkpoint. | | Model-visible context | What the model actually receives in a request | Replaced. Older context becomes