<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Token on Fengze's Blog</title><link>https://caifengze.com/en/tags/token/</link><description>Recent content in Token on Fengze's Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 05 Feb 2026 21:00:00 -0500</lastBuildDate><atom:link href="https://caifengze.com/en/tags/token/index.xml" rel="self" type="application/rss+xml"/><item><title>Why Does OpenClaw Consume Tokens So Fast?</title><link>https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/</link><pubDate>Thu, 05 Feb 2026 21:00:00 -0500</pubDate><guid>https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/</guid><description>&lt;img src="https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/overview.png" alt="Featured image of post Why Does OpenClaw Consume Tokens So Fast?" />&lt;h1 id="why-does-openclaw-consume-tokens-so-fast">Why Does OpenClaw Consume Tokens So Fast?
&lt;/h1>&lt;p>The first part of this article answers a fundamental yet critical question:&lt;/p>
&lt;h2 id="what-does-openclaw-actually-send-to-the-model-per-interaction">What Does OpenClaw Actually Send to the Model Per Interaction?
&lt;/h2>&lt;p>When we say &amp;ldquo;the context is large and tokens are consumed quickly,&amp;rdquo; we essentially mean that every time OpenClaw calls the model API, it sends a &amp;ldquo;complete input&amp;rdquo; to the model — one that far exceeds the user&amp;rsquo;s single message.&lt;/p>
&lt;p>Here is a breakdown of what this input consists of and where it comes from.&lt;/p>
&lt;p>&lt;strong>1. System Prompt&lt;/strong>&lt;/p>
&lt;p>The system prompt is the &amp;ldquo;instruction manual&amp;rdquo; that OpenClaw includes with every model call. It contains multiple fixed or semi-fixed sections, with the core purpose of telling the model what it is, what tools it has, which working directory it&amp;rsquo;s in, how to handle memory and channel messages, and so on.&lt;/p>
&lt;p>The system prompt is a &amp;ldquo;big box&amp;rdquo; that includes the following sub-blocks:&lt;/p>
&lt;ul>
&lt;li>Tooling section: lists available tools and brief descriptions.&lt;/li>
&lt;li>Safety section: basic safety and behavioral constraints.&lt;/li>
&lt;li>Skills section: skill directory prompt (can be very long, growing with the number of skills).&lt;/li>
&lt;li>Memory section: memory retrieval specification (tells the model to search MEMORY.md first, etc.).&lt;/li>
&lt;li>Documentation section: local documentation path hints.&lt;/li>
&lt;li>Workspace section: current working directory + notes.&lt;/li>
&lt;li>Project Context section: injected context file content (usually the largest portion).&lt;/li>
&lt;li>Messaging/Voice/Reply Tags/Sandbox/Runtime and other auxiliary sections.&lt;/li>
&lt;/ul>
&lt;p>The reason sections 2–4 below are covered separately is to highlight their &amp;ldquo;contribution&amp;rdquo; to token volume — they are not independent parts outside the system prompt.&lt;/p>
&lt;p>The system prompt construction logic is concentrated in:&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-runner/system-prompt.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. Project Context Injection&lt;/strong>&lt;/p>
&lt;p>This is one of the most significant contributors to token consumption. Before each run, OpenClaw reads a set of workspace &amp;ldquo;bootstrap files&amp;rdquo; and injects their full content into the system prompt.&lt;/p>
&lt;p>The files read by default include:&lt;/p>
&lt;ul>
&lt;li>&lt;code>AGENTS.md&lt;/code>&lt;/li>
&lt;li>&lt;code>SOUL.md&lt;/code>&lt;/li>
&lt;li>&lt;code>TOOLS.md&lt;/code>&lt;/li>
&lt;li>&lt;code>IDENTITY.md&lt;/code>&lt;/li>
&lt;li>&lt;code>USER.md&lt;/code>&lt;/li>
&lt;li>&lt;code>HEARTBEAT.md&lt;/code>&lt;/li>
&lt;li>&lt;code>BOOTSTRAP.md&lt;/code>&lt;/li>
&lt;li>&lt;code>MEMORY.md&lt;/code> or &lt;code>memory.md&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Each file is trimmed (default single-file limit: 20,000 chars), then inserted in the following format:&lt;/p>
&lt;pre tabindex="0">&lt;code># Project Context
## BOOTSTRAP.md
&amp;lt;content&amp;gt;
&lt;/code>&lt;/pre>&lt;p>The logic resides in:&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/workspace.ts&lt;/code> (reads file collection)&lt;/li>
&lt;li>&lt;code>src/agents/bootstrap-files.ts&lt;/code> (assembles injection)&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-helpers/bootstrap.ts&lt;/code> (trimming)&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code> (final injection)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>3. Skills List&lt;/strong>&lt;/p>
&lt;p>If skills are enabled, OpenClaw compiles all skills into a directory section and injects it into the system prompt. This list grows linearly with the number of skills and the length of their descriptions.&lt;/p>
&lt;p>These are not &amp;ldquo;tools&amp;rdquo; but rather &amp;ldquo;workflow instructions&amp;rdquo; — the model reads SKILL.md based on the prompt.&lt;/p>
&lt;p>Related logic:&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/skills/workspace.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>4. Tool Definitions (Tool List + Schema)&lt;/strong>&lt;/p>
&lt;p>The list of tools the model can actually call (e.g., &lt;code>read&lt;/code>, &lt;code>exec&lt;/code>, &lt;code>message&lt;/code>) is injected into the system prompt. Tool parameter schemas are also passed to the model. This part is usually not fully displayed in the prompt, but it still consumes input tokens.&lt;/p>
&lt;p>Related logic:&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-tools.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>5. Conversation History + Tool Results&lt;/strong>&lt;/p>
&lt;p>In addition to the system prompt, OpenClaw also sends the session&amp;rsquo;s historical messages and tool call results to the model. This history accumulates continuously until compaction or memory flush is triggered.&lt;/p>
&lt;p>Related logic:&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code> (loads history)&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-runner/compact.ts&lt;/code> (compaction)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>6. Current User Input&lt;/strong>&lt;/p>
&lt;p>Finally, the user&amp;rsquo;s current message — combined with everything above, it forms the &amp;ldquo;complete input for this API call.&amp;rdquo;&lt;/p>
&lt;p>&lt;strong>Summary: A single interaction is far more than &amp;ldquo;just sending your one message.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Each time OpenClaw calls the model, it sends:&lt;/p>
&lt;ul>
&lt;li>System prompt (very long)&lt;/li>
&lt;li>Project context (very long)&lt;/li>
&lt;li>Skills list (can be very long)&lt;/li>
&lt;li>Tool schemas (can be very long)&lt;/li>
&lt;li>Conversation history and tool results (keeps growing)&lt;/li>
&lt;li>Current user message&lt;/li>
&lt;/ul>
&lt;p>This is why tokens grow so fast.&lt;/p>
&lt;p>&lt;img src="https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/overview.png"
width="4284"
height="2112"
srcset="https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/overview_hu_e49c0d2ff66be2e5.png 480w, https://caifengze.com/en/blog/2026/why-does-openclaw-consume-tokens-so-fast/overview_hu_27464601b4dee01f.png 1024w"
loading="lazy"
alt="OpenClaw token flow overview"
class="gallery-image"
data-flex-grow="202"
data-flex-basis="486px"
>&lt;/p>
&lt;p>&lt;em>Figure: The relationship between system prompt, session history, user input, and sub-agent/fallback/compaction in a single request.&lt;/em>&lt;/p>
&lt;p>&lt;strong>Code Evidence: The &amp;ldquo;Final Assembly Point&amp;rdquo; of the System Prompt&lt;/strong>&lt;/p>
&lt;p>Below is a key snippet from &lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>, which clearly shows what gets packaged into the system prompt (simplified):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// src/agents/pi-embedded-runner/run/attempt.ts
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">appendPrompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">buildEmbeddedSystemPrompt&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">skillsPrompt&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Skills list
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">contextFiles&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Project Context (BOOTSTRAP, etc.)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">tools&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Tool list + schema
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">docsPath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Documentation hints
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">runtimeInfo&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Runtime environment info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">workspaceNotes&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Workspace hints
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">sandboxInfo&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Sandbox info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">modelAliasLines&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Model aliases
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ... and more auxiliary info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="a-single-request-may-trigger-multiple-api-calls-tool-call-chains">A Single Request May Trigger Multiple API Calls: Tool Call Chains
&lt;/h2>&lt;p>A single &amp;ldquo;user request&amp;rdquo; doesn&amp;rsquo;t necessarily result in just one model API call. The most common reason is &lt;strong>tool call chains&lt;/strong>:&lt;/p>
&lt;ol>
&lt;li>After seeing the tool list, the model initiates a tool call (e.g., &lt;code>read&lt;/code> / &lt;code>exec&lt;/code>).&lt;/li>
&lt;li>OpenClaw executes the tool and produces a tool result.&lt;/li>
&lt;li>The tool result is written back to the session (as a tool message).&lt;/li>
&lt;li>The model continues generating, initiating the next tool call if necessary.&lt;/li>
&lt;/ol>
&lt;p>This means a single user input may produce multiple rounds of model interaction, thereby consuming tokens faster.&lt;/p>
&lt;p>Corresponding code entry points (simplified paths):&lt;/p>
&lt;ul>
&lt;li>Tool definitions: &lt;code>src/agents/pi-tools.ts&lt;/code>&lt;/li>
&lt;li>Session creation + tools injection: &lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>&lt;/li>
&lt;li>Subscribing to tool events: &lt;code>src/agents/pi-embedded-subscribe.ts&lt;/code>&lt;/li>
&lt;li>Tool execution lifecycle handling: &lt;code>src/agents/pi-embedded-subscribe.handlers.tools.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="failure-retry--fallback-how-model-fallback-and-retry-work">Failure Retry / Fallback: How Model Fallback and Retry Work
&lt;/h2>&lt;p>OpenClaw doesn&amp;rsquo;t just give up when something goes wrong. When a model call fails (timeout, rate limiting, authentication errors, etc.), the system attempts &lt;strong>model fallback&lt;/strong>, continuing with the next model in the candidate list.&lt;/p>
&lt;p>The core logic is implemented in &lt;code>runWithModelFallback&lt;/code>:&lt;br>
&lt;code>src/agents/model-fallback.ts&lt;/code>&lt;/p>
&lt;p>The logic is very straightforward:&lt;/p>
&lt;ol>
&lt;li>Generate a &amp;ldquo;candidate model list&amp;rdquo; based on configuration (from &lt;code>agents.defaults.model.fallbacks&lt;/code> or overrides passed at call time).&lt;/li>
&lt;li>Try calling models one by one in order.&lt;/li>
&lt;li>Only proceed to the next fallback if the error is classified as a &lt;strong>FailoverError&lt;/strong>; otherwise, throw the error directly.&lt;/li>
&lt;/ol>
&lt;p>This means &lt;strong>a single user request may trigger multiple API calls due to the fallback mechanism&lt;/strong>. Of course, this is a good thing.&lt;/p>
&lt;h2 id="compaction-and-memory-flush-what-happens-when-context-is-nearly-full">Compaction and Memory Flush: What Happens When Context Is Nearly Full
&lt;/h2>&lt;p>When the context is nearly full, OpenClaw may trigger &lt;strong>two different types of additional model calls&lt;/strong>:&lt;br>
One is &lt;strong>Compaction (summary compression)&lt;/strong>, and the other is &lt;strong>Memory Flush (memory write-out)&lt;/strong>. They serve different purposes and follow different processes.&lt;/p>
&lt;h3 id="1-compaction-summary-compression">1. Compaction (Summary Compression)
&lt;/h3>&lt;p>Goal: Compress the conversation history into &amp;ldquo;shorter summaries&amp;rdquo; to free up context space.&lt;/p>
&lt;p>Implementation logic: &lt;code>src/agents/compaction.ts&lt;/code>&lt;/p>
&lt;p>Key points:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Does not send the entire history to the model at once&lt;/strong>&lt;br>
Instead, it splits the history into chunks by token count, calls the model to generate a summary for each chunk, then merges them into one final summary.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>If a single message is too large&lt;/strong>&lt;br>
It falls back to summarizing only the small messages, using placeholder hints for large ones.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Simplified flow:&lt;/p>
&lt;pre tabindex="0">&lt;code>History messages → Split by token count → Model summarizes each chunk → Merge summaries
&lt;/code>&lt;/pre>&lt;h3 id="2-memory-flush-memory-write-out">2. Memory Flush (Memory Write-Out)
&lt;/h3>&lt;p>Goal: Before compaction, write &amp;ldquo;long-term memories&amp;rdquo; to disk (&lt;code>memory/YYYY-MM-DD.md&lt;/code>).&lt;/p>
&lt;p>Trigger logic: &lt;code>src/auto-reply/reply/agent-runner-memory.ts&lt;/code>&lt;br>
Prompts and default text: &lt;code>src/auto-reply/reply/memory-flush.ts&lt;/code>&lt;/p>
&lt;p>Key points:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Not summarizing history&lt;/strong>&lt;br>
Rather, it asks the model to organize &amp;ldquo;memories worth long-term preservation&amp;rdquo; and writes them to the &lt;code>memory/&lt;/code> directory.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>This is an additional round of model calls&lt;/strong>&lt;br>
Its purpose is to preserve persistent memories, not to compress context.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="sub-agent--sessions_spawn-how-parallelism-and-task-division-cause-additional-calls">Sub-Agent / sessions_spawn: How Parallelism and Task Division Cause Additional Calls
&lt;/h2>&lt;p>When a task is complex, time-consuming, or suitable for parallelism, the main agent may call the &lt;code>sessions_spawn&lt;/code> tool to delegate subtasks to sub-agents. This starts a &lt;strong>completely new sub-session&lt;/strong> with its own sessionKey, system prompt, and tool pipeline, resulting in additional model calls.&lt;/p>
&lt;p>Core entry point: &lt;code>src/agents/tools/sessions-spawn-tool.ts&lt;/code>&lt;/p>
&lt;p>Simplified flow:&lt;/p>
&lt;ol>
&lt;li>The main agent calls &lt;code>sessions_spawn&lt;/code> (this is a tool call choice made by the model).&lt;/li>
&lt;li>The system generates a &lt;code>childSessionKey&lt;/code> (&lt;code>agent:&amp;lt;id&amp;gt;:subagent:&amp;lt;uuid&amp;gt;&lt;/code>).&lt;/li>
&lt;li>Constructs the sub-agent&amp;rsquo;s system prompt (&lt;code>buildSubagentSystemPrompt&lt;/code>).&lt;/li>
&lt;li>Launches the sub-agent&amp;rsquo;s independent run flow via &lt;code>callGateway&lt;/code>.&lt;/li>
&lt;li>After the sub-agent completes its task, the result is passed back to the main session.&lt;/li>
&lt;/ol>
&lt;p>In short, &lt;strong>a sub-agent is &amp;ldquo;starting an entirely new complete session.&amp;rdquo;&lt;/strong> Therefore, it significantly increases the total number of API calls and token consumption.&lt;/p></description></item></channel></rss>