# How Session Compaction Reduces Context Size in Pi Web

> Session compaction in pi-web slashes context size by summarizing old conversations into a single entry. Learn how this improves model efficiency and performance.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: deep-dive
- Published: 2026-07-23

---

**Session compaction in pi-web reduces context size by replacing old conversation entries with a single `CompactionEntry` that contains a summary and metadata, allowing the model to ingest only recent entries plus one condensed block instead of the full history.**

As conversations with the coding agent grow longer, the session file (`.jsonl`) accumulates entries that can overwhelm model token limits or degrade performance. The `agegr/pi-web` repository solves this through an intelligent compaction mechanism that archives older interactions while preserving essential context.

## The Problem: Expanding Session Logs

Pi Web stores every interaction in a JSONL session file. Each message, tool call, and response appends new entries, progressively increasing the token count the model must process. Without intervention, long-running sessions eventually hit context windows or cause sluggish response times.

## How Compaction Works in Pi Web

When compaction triggers—either manually by the user or automatically—the agent scans the session log, identifies a cutoff point, and consolidates everything before that point into a single specialized entry.

### The CompactionEntry Structure

The replacement entry is defined in [`lib/types.ts`](https://github.com/agegr/pi-web/blob/main/lib/types.ts) at lines 23-28:

```ts
interface CompactionEntry extends SessionEntryBase {
  type: "compaction";
  summary: string;          // Human‑readable summary of removed content
  firstKeptEntryId: string; // Id of the first entry that remains after compaction
  tokensBefore: number;     // Token count before compaction
}

```

This structure preserves three critical pieces of metadata: a human-readable **summary** of the discarded content, the **firstKeptEntryId** marking where the retained history begins, and the **tokensBefore** count for UI feedback.

### Triggering Manual and Automatic Compaction

Users initiate manual compaction through the RPC manager. In [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts), the `compact` command is processed and forwarded to the agent:

```tsx
// Trigger a manual compaction from the UI
await sendAgentCommand(sessionId, { type: "compact", customInstructions: undefined });

```

The system also supports automatic compaction via `auto_compaction_start` events, which trigger when the session reaches predefined token thresholds.

## Building Context After Compaction

Once compaction completes, the context builder must respect the new boundaries to realize the token savings.

### Session Context Assembly

In [`lib/session-reader.ts`](https://github.com/agegr/pi-web/blob/main/lib/session-reader.ts), the `buildSessionContext` function uses `firstKeptEntryId` to determine where to start assembling messages. Rather than processing the entire file from the beginning, it begins at the first retained entry, treating the preceding `CompactionEntry` as a single token block. This effectively truncates the context while maintaining semantic continuity through the summary.

According to the pi-web source code, this mechanism can reduce context from thousands of tokens to a few hundred, keeping sessions within model limits without losing historical awareness.

### UI State Management

The frontend monitors compaction lifecycle events in [`hooks/useAgentSession.ts`](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts) at lines 1004-1011. When the agent emits `compaction_start` or `auto_compaction_start`, the UI displays a loading spinner and disables the Compact button. Upon receiving `compaction_end` or `auto_compaction_end`, it clears the spinner, surfaces any errors, and reloads the session to display the compacted view:

```tsx
// The UI receives the compaction_end event and reloads the session (hooks/useAgentSession.ts)

```

## Session Compaction in Practice

The compaction process follows three distinct steps to minimize context size:

1. **Summarize** – The agent generates a concise description of the removed conversation history.
2. **Truncate** – All entries before the cutoff are discarded from the active context, retaining only recent entries from `firstKeptEntryId` onward.
3. **Consolidate** – The removed bulk is replaced by the single `CompactionEntry`, which the model treats as one discrete token block instead of many individual messages.

## Summary

- **Session compaction** replaces old `.jsonl` entries with a single `CompactionEntry` defined in [`lib/types.ts`](https://github.com/agegr/pi-web/blob/main/lib/types.ts).
- The `firstKeptEntryId` property marks the boundary between summarized history and active conversation.
- **Token reduction** is achieved by treating the compaction entry as one block while starting context assembly from the retained entries in [`lib/session-reader.ts`](https://github.com/agegr/pi-web/blob/main/lib/session-reader.ts).
- The UI manages compaction states through events handled in [`hooks/useAgentSession.ts`](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts), ensuring responsive feedback during the archival process.

## Frequently Asked Questions

### What triggers session compaction in pi-web?

Session compaction triggers either manually when the user clicks the Compact button—which sends a `compact` command via [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)—or automatically when the conversation exceeds configured token thresholds, emitting `auto_compaction_start` events.

### How does the model know which entries to ignore after compaction?

The `buildSessionContext` function in [`lib/session-reader.ts`](https://github.com/agegr/pi-web/blob/main/lib/session-reader.ts) references the `firstKeptEntryId` stored in the `CompactionEntry`. It begins assembling the message context from that entry ID forward, effectively ignoring all preceding entries while still ingesting the summary as a single token block.

### Does compaction delete data permanently?

No, compaction creates a new session state where old entries are archived into the `CompactionEntry` summary, but the original `.jsonl` structure remains intact. The system primarily affects how the context is presented to the model, not the underlying data storage, though the UI reloads to show the compacted view after `compaction_end` events.

### What information does a CompactionEntry contain?

According to [`lib/types.ts`](https://github.com/agegr/pi-web/blob/main/lib/types.ts) lines 23-28, each `CompactionEntry` contains three fields: a **summary** describing the removed content, the **firstKeptEntryId** identifying where the retained portion begins, and **tokensBefore** indicating how many tokens were eliminated to provide transparency in the UI.