Token Use and Cost Tracking in OpenClaw

Learn how OpenClaw measures token usage, builds system prompts, and reports costs. Essential for developers managing API budgets and optimizing context.

Read this when

  • Explaining token usage, costs, or context windows
  • Debugging context growth or compaction behavior

OpenClaw measures usage in tokens rather than characters. While token counts vary by model, most OpenAI-style models convert roughly 4 characters into a single token for English text.

How the system prompt is built

A fresh system prompt is generated by OpenClaw for every run. Its contents are:

  • Tool list with brief descriptions
  • Skills list (metadata only; full instructions load on demand through read). Native Codex turns receive the compact skills block as turn-scoped collaboration developer instructions; other harnesses get it in the normal prompt surface. Limited by skills.limits.maxSkillsPromptChars, with an optional per-agent override at agents.entries.*.skillsLimits.maxSkillsPromptChars.
  • Self-update instructions
  • Workspace and bootstrap files (AGENTS.md, SOUL.md, IDENTITY.md, USER.md, BOOTSTRAP.md when new, plus MEMORY.md when present). Large injected files get truncated via agents.defaults.bootstrapMaxChars (default: 20000); total bootstrap injection is limited by agents.defaults.bootstrapTotalMaxChars (default: 60000).
    • For native Codex turns, raw MEMORY.md is not pasted when memory tools exist for that workspace; instead, a small memory pointer appears in turn-scoped collaboration developer instructions, and memory tools are called on demand. When tools are disabled, memory search is unavailable, or the active workspace differs from the agent memory workspace, MEMORY.md falls back to the standard bounded turn-context path.
    • Lowercase root memory.md is never injected. It serves as legacy repair input for openclaw doctor --fix, which migrates it into MEMORY.md.
    • Daily files under memory/*.md stay out of the standard bootstrap prompt; they remain on-demand via memory tools on ordinary turns. Reset/startup model runs may prepend a one-shot startup-context block containing recent daily memory for that first turn, governed by agents.defaults.startupContext. Bare chat /new and /reset are acknowledged without triggering the model.
    • Post-compaction AGENTS.md excerpts need explicit agents.defaults.compaction.postCompactionSections opt-in; plugins can add other context through before_prompt_build.
  • Time (UTC plus user timezone)
  • Reply tags and heartbeat behavior
  • Runtime metadata (host/OS/model/thinking)

A complete breakdown is available in System Prompt.

When documenting credentials or auth snippets, follow the Secret Placeholder Conventions to prevent secret-scanner false positives in docs-only changes.

What counts in the context window

Anything the model receives is charged against the context limit:

  • System prompt (all sections listed above)
  • Conversation history (user and assistant messages)
  • Tool calls and their results
  • Attachments/transcripts (images, audio, files)
  • Compaction summaries and pruning artifacts
  • Provider wrappers or safety headers (invisible but still counted)

Runtime-heavy surfaces carry their own explicit caps under agents.defaults.contextLimits (per-agent overrides under agents.entries.*.contextLimits):

KeyPurpose
memoryGetMaxCharsMax characters memory_get returns before truncation.
postCompactionMaxCharsMax characters retained from AGENTS.md during post-compaction refresh.

These are bounded runtime excerpts and injected runtime-owned blocks, separate from bootstrap limits, startup-context limits, and skills prompt limits.

The live tool-result cap is derived by OpenClaw from the effective model context window: 16000 chars below 100K tokens, 32000 chars at 100K+ tokens, 64000 chars at 200K+ tokens. Additionally, the runtime context-share guard limits a single tool result to 30% of the context window.

Large provider windows are not turned on automatically when they materially change cost or latency. For instance, direct OpenAI GPT-5.5 and GPT-5.6 models publish a 1050000 token total window, but OpenClaw defaults their active runtime budget to 272000 tokens. The opt-in 922000 input budget reserves the full 128000 output allowance, and OpenAI applies higher long-context pricing to the entire request once input exceeds 272000 tokens. See OpenAI context window defaults.

For images, OpenClaw downscales transcript/tool image payloads before provider calls. Tune with agents.defaults.imageMaxDimensionPx (default: 1200):

  • Lower values cut vision-token usage and payload size.
  • Higher values keep more visual detail for OCR/UI-heavy screenshots.

For a practical breakdown (per injected file, tools, skills, and system prompt size), use /context list or /context detail. See Context.

How to see current token usage

In chat:

  • /status maps to an emoji-heavy status card that shows the session model, context usage, tokens for the last response's input and output, plus the estimated cost when local pricing is set up for the currently active model.
  • /usage off|tokens|full adds a usage footer to each reply, detailing per-response metrics. This setting persists per session and is saved as responseUsage.
    • /usage reset (also known as inherit, clear, or default) removes the session-level override, letting the session fall back to the configured default.
    • /usage tokens reveals turn-level token and cache specifics.
    • /usage full gives a compact view of model, context, and cost details; the estimated cost only shows up when OpenClaw holds usage metadata and local pricing for the active model. Custom messages.usageTemplate layouts may incorporate token and cache fields.
  • /usage cost pulls a local cost summary straight from OpenClaw's session logs.

Other interfaces:

  • TUI/Web TUI: Both /status and /usage are available.
  • CLI: openclaw status --usage and openclaw channels list display normalized provider quota windows (X% left, not per-response costs). Providers with current usage windows include Claude (Anthropic), ClawRouter, Copilot (GitHub), DeepSeek, MiniMax, OpenAI, Xiaomi, Xiaomi Token Plan, and z.ai.

Before anything is shown, usage surfaces standardize common provider-native field aliases. For OpenAI-family Responses traffic, this covers both input_tokens/output_tokens and prompt_tokens/completion_tokens, so transport-specific field names leave /status, /usage, and session summaries unchanged. Gemini CLI usage also gets normalized: the default stream-json parser reads assistant message events, stats.cached is mapped to cacheRead, and stats.input_tokens - stats.cached applies when the CLI leaves out an explicit stats.input field. Legacy JSON overrides continue to read reply text from response.

For native OpenAI-family Responses traffic, WebSocket/SSE usage aliases normalize the same way, and totals fall back to normalized input plus output when total_tokens is absent or 0 is present.

If the current session snapshot lacks detail, /status and session_status can retrieve token/cache counters and the active runtime model label from the most recent transcript usage log. Any existing nonzero live values still take priority over transcript fallback values, and larger prompt-oriented transcript totals can win when stored totals are missing or smaller.

Provider quota window authentication comes from provider-specific hooks first; when a provider has no hook, or the hook fails to resolve a token, OpenClaw falls back to matching OAuth/API-key credentials from auth profiles, env, or config.

Assistant transcript entries store the same normalized usage shape, including usage.cost when the active model has pricing configured and the provider returns usage metadata. This gives /usage cost and transcript-backed session status a stable source even after the live runtime state is gone.

OpenClaw keeps provider usage accounting separate from the current context snapshot. Provider usage.total can include cached input, output, and multiple tool-loop model calls, so it's useful for cost and telemetry but can overstate the live context window. Context displays and diagnostics use the latest prompt snapshot (promptTokens, or the last model call when no prompt snapshot is available) for context.used.

Cost estimation (when shown)

Costs come from your model pricing config:

models.providers.<provider>.models[].cost

These are USD per 1M tokens for input, output, cacheRead, and cacheWrite. If pricing is absent, /usage full omits cost; use /usage tokens or a custom messages.usageTemplate when you need token/cache details in every reply. Cost display isn't limited to API-key auth: non-API-key providers such as aws-sdk can show estimated cost when their configured model entry includes local pricing and the provider returns usage metadata.

Pricing updates ship in the hosted model catalog alongside model metadata. OpenClaw does not fetch OpenRouter or LiteLLM directly. Set models.catalogRefresh.enabled: false to disable hosted catalog traffic on offline or restricted networks; bundled pricing and explicit models.providers.*.models[].cost entries still drive local cost estimates.

Cache TTL and pruning impact

Provider prompt caching only applies within the cache TTL window. OpenClaw can optionally run cache-ttl pruning: it prunes the session once the cache TTL has expired, then resets the cache window so subsequent requests re-use the freshly cached context instead of re-caching the full history. This keeps cache write costs lower when a session goes idle past the TTL.

Configure it in Gateway configuration and see the behavior details in Session pruning.

Heartbeat can keep the cache warm across idle gaps. If your model cache TTL is 1h, setting the heartbeat interval just under that (e.g., 55m) can avoid re-caching the full prompt, reducing cache write costs.

In multi-agent setups, you can keep one shared model config and tune cache behavior per agent with agents.entries.*.params.cacheRetention.

For a full knob-by-knob guide, see Prompt Caching.

For Anthropic API pricing, cache reads are significantly cheaper than input tokens, while cache writes are billed at a higher multiplier. See Anthropic's prompt caching pricing for the latest rates and TTL multipliers: https://platform.claude.com/docs/en/build-with-claude/prompt-caching

Example: keep 1h cache warm with heartbeat

agents:
  defaults:
    model:
      primary: "anthropic/claude-opus-4-6"
    models:
      "anthropic/claude-opus-4-6":
        params:
          cacheRetention: "long"
    heartbeat:
      every: "55m"

Example: mixed traffic with per-agent cache strategy

agents:
  defaults:
    model:
      primary: "anthropic/claude-opus-4-6"
    models:
      "anthropic/claude-opus-4-6":
        params:
          cacheRetention: "long" # default baseline for most agents
  list:
    - id: "research"
      default: true
      heartbeat:
        every: "55m" # keep long cache warm for deep sessions
    - id: "alerts"
      params:
        cacheRetention: "none" # avoid cache writes for bursty notifications

agents.entries.*.params is applied on top of the params from the chosen model, letting you change only cacheRetention while all other model defaults stay untouched.

Anthropic 1M context

For GA-capable Claude 4.x models like Opus 4.8, Opus 4.7, Opus 4.6, and Sonnet 4.6, OpenClaw configures Anthropic's 1M context window. Those models don't require params.context1m: true.

agents:
  defaults:
    models:
      "anthropic/claude-opus-4-6":
        alias: opus

Legacy configurations may continue using context1m: true, but OpenClaw no longer transmits Anthropic's deprecated context-1m-2025-08-07 beta header for this option, nor does it scale up unsupported older Claude models to 1M.

Requirement: the credential must qualify for long-context use. Otherwise, Anthropic returns a provider-side rate limit error for that specific request.

When authenticating with Anthropic via OAuth or subscription tokens (sk-ant-oat-*), OpenClaw keeps the Anthropic beta headers that OAuth mandates while removing the obsolete context-1m-* beta if it still appears in older configs.

Tips for reducing token pressure

  • Apply /compact to condense lengthy sessions.
  • Reduce large tool outputs within your workflows.
  • Decrease agents.defaults.imageMaxDimensionPx for sessions heavy on screenshots.
  • Keep skill descriptions brief, since the skill list is injected into the prompt.
  • Choose smaller models for verbose, exploratory tasks.

Refer to Skills for the exact formula behind skill list overhead.

1,719 words · updated Aug 4, 2026