Restart the Conversation, or Compact the History? How Pi Solves Automatic Context Compaction

A long task doesn't keep going because the model has a good memory. It just keeps stuffing the past into each next request; when it no longer fits, Pi rewrites its own working memory.

By Earendil Engineering08-17 · 10 min⚑ Research paper
🎧 Listen to the podcast0:00 / --:--
0:00 / --:--
Research Explainer · XiaoHu Explains
One-minute overview
  • Compacting context rewrites earlier work into a shorter state summary to free up context space for long tasks.
  • Pi by default keeps roughly the most recent 20k tokens and reserves 16,384 tokens for the next response; these numbers are Pi-specific, not industry-wide.
  • Compaction is a lossy migration: it preserves work continuity but loses details and temporarily invalidates old prompt caches.

If you've had Pi, Claude Code, or Codex continuously edit code, check logs, and run tests, you've likely seen a prompt like compacting context when the task runs long enough.

It's not compressing code or deleting files. It means the current session is nearing the limit of information the model can read at once, and the coding agent is rewriting earlier work records into a shorter version so the task can continue.

This finite space is called the context window. Each time the model answers, it can only reference what fits in the window. Long tasks keep adding new messages, code, logs, tool calls, and results, so the window fills up. compacting context appears because the agent must make room for subsequent work before hitting the capacity limit.

Earendil Engineering wrote a dedicated piece, “How Compaction Works in Pi,” dissecting Pi's approach. Pi is a coding agent that runs in the terminal. The following describes its specific implementation; other coding agents face the same general problem, but their trigger thresholds, retention amounts, and summarization methods may differ.

Models Don't Remember, They Replay Context

Imagine you ask the agent to fix a payment issue, saying only, “Check why checkout returns 502.” But the model actually receives more than that: the system prompt, tool definitions, and project rule files. When it calls the log tool, the tool results also enter the history; when you add another clue, the next request carries all previous content again.

The agent isn't permanently remembering the work in some hidden brain region. It's re-presenting the current work state to the model on every request.

Capacity, not memoryEach step forward means the next request carries more historyBar heights show cumulative context usage trends, not fixed Pi measurements.
RulesTool resultsNew messagesCode and logs keep appending

Each step makes sense, but the cumulative result is one: history grows monotonically, and the task might not be done yet. When the context can't hold any more, the agent can't keep carrying the past along verbatim; it must decide what content is still worth keeping.

Restart the Conversation, or Compact the History

Once the current session can't continue as-is, the agent has two basic paths. It can start a new session, immediately reclaiming all space, but goals, completed work, key decisions, and unresolved issues also leave. Or it can do compaction: replace part of the old history with a shorter representation and continue along the current task.

Pi chooses the second path. Here “compression” isn't like a zip archive that can be losslessly restored later. Pi typically has the model write a summary of old history; space comes from trade-offs: details are lost, wording is condensed, and information that appeared only once may fade over time.

So a more accurate name for compaction is lossy work-state migration. It doesn't aim to preserve every sentence, but to ensure the next model still knows: what the goal is, what's been done, which decisions can't be reversed, where things are stuck, and what to do next.

How Pi Splits Old and New Context

Pi doesn't summarize the entire conversation in one go. It first counts back from the latest message and draws a cut line. According to the current official docs and the pinned source version, automatic compaction triggers when contextTokens > contextWindow - reserveTokens. By default, it reserves 16,384 tokens for the upcoming response and tries to keep the most recent 20,000 tokens intact.

20k is a budget, not a fixed number of messages. If the recent turns are stuffed with logs and code, fewer turns can be kept. The original article roughly converts it to 5–20 turns, but that's not a guarantee.

One cut, two treatmentsOld history gets summarized, recent work passes through intactCompaction doesn't shrink the entire context at once.
Before compaction
Before the cut: summarizeAfter the cut: keep
After compaction
Loss happens at the summary stageRecent work still enters the new request in original order, but earlier history can only retain the goals, decisions, progress, and critical context that the summarizer identified.

Default reserves 16,384 tokens for the new response; the recent 20k is a budget, not a fixed number of turns — both are Pi's configurable implementation.

Content before the cut is extracted, serialized, and summarized; content after the cut still enters the new request in original order. Pi typically checks for automatic compaction after a turn ends. If the model returns an over-limit error mid-turn, it might compact on the spot and retry.

Users can also manually run /compact [instructions] to compact early when needed, with additional instructions to remind the summarizer to preserve certain information. This entry point can change timing and focus, but it still can't turn a lossy summary into unlimited memory.

The Summary Is a Work Handoff

A regular summary cares about “what was just talked about.” A work handoff cares about: can the next person start working right away.

Pi initiates a separate model request, changing the role to context summarization assistant, instructing it not to continue the current conversation but to output a structured checkpoint. The current prompt requires preserving six categories:

  • Goal: What the user ultimately wants to accomplish.
  • Constraints & Preferences: Limits and preferences that must not be violated.
  • Progress: Completed, in-progress, and blocked items.
  • Key Decisions: Key choices and their rationale.
  • Next Steps: The order in which to proceed.
  • Critical Context: Paths, functions, errors, and other precise information.

The generated result is written back to the session as a plain-text CompactionEntry. The new request then becomes:

[system] [tools] [summary] [recent turns] [new user]

The beauty of plain text is simple: a human can check whether the summary missed any key decisions, and Pi can continue using it after switching models. What's migrated is visible work state, not some uncheckable memory inside a model.

But this handoff only preserves what the summarizer recognized. If an important constraint appeared only once very early, it may still fade through repeated compactions. Truly critical project rules are best written into AGENTS.md, task status, code, or other persistent records.

Prefix Changes, Old Cache Goes Stale

Compaction frees up space, but it also changes the most sensitive part of each request: the prefix.

Prompt caching from model providers typically relies on exact prefix matching. Before compaction, the next request mostly continues appending to the old history; after compaction, earlier history is replaced by a new summary. Even if the recent turns haven't changed a single word, what precedes them is different, so the old cache can't be reused from the same position.

Cache compares full prefixesTails are identical, but the head changed, so fingerprints differPrompt cache doesn't just look at recent turns; it checks exact match from the start of the request.
Before compactionPrefix fingerprintA91C
Old cache breaks here
After compactionPrefix fingerprint5F2E
Same recent messages ≠ same prefixThe summary replaces earlier content, so the same messages after it must be recomputed.

The invalidation isn't permanent: the compacted structure becomes the new prefix, and subsequent requests can rebuild cache on top of it.

This isn't a permanent loss of cache. The compacted structure becomes the new stable prefix, and subsequent requests can accumulate cache on top of it again. This also explains why Pi tries to compact after a turn ends: let this turn's continuous requests enjoy the old prefix's cache benefits, then rewrite the context.

Can We Get Straight to Work After Compaction?

Pi's trade-offs are now complete: keeping all history hits the context limit; compacting history loses details and costs a cache recompute; starting a completely new session abandons work continuity altogether.

To judge whether a compaction is good, ask four questions: How much recent work remains intact? Does the summary preserve goals, decisions, progress, and next steps? Can the result be inspected by a human and migrated between models? Does the trigger timing strike a reasonable balance between remaining space, overflow risk, and cache cost?

Good compaction isn't “remembering all the past.” It's accepting that forgetting is inevitable, then doing your best to hand off the work state that truly affects the next step.

Source
How Compaction Works in PiEarendil Engineering·2026-08-13·View primary source
↑ End of article
✓ This article is free to read in full

Members can copy or download the full Markdown, and let their AI subscribe and ask.

Read the original ↗
📮 New explainers, straight to your inbox

Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.