Skip to content

[Bug]: 5x API costs due to ineffective prompt caching #23715

Description

@svenssonaxel

Summary

Prompt caching ineffective due to shared system prompt prefix across all users

Steps to reproduce

  • Use OpenClaw with OpenRouter, locking your openrouter account to any particular provider that supports cache read.
  • Issue a few chat messages in rapid succession
  • Investigate the cost structure in the openrouter log.

Expected behavior

The first request has 0 cache read tokens, and a high number of input tokens.
All subsequent requests (likely) have a high number of cache read tokens and almost no read tokens.

Actual behavior

All requests (likely) have either 0 or approximately 4k cache read tokens. The number of input tokens remain high for every or almost every request.

OpenClaw version

2026.2.19

Operating system

Debian

Install method

nix-openclaw

Logs, screenshots, and evidence

Impact and severity

Affected: All users of inference APIs
Severity: Exorbitant expense
Frequency: Always, except for the first request after a (typically) 5 minute idle period.
Consequence: API costs ~5x higher than necessary

Additional information

The mechanism

  • OpenClaw's system prompt has a long prefix (~4k tokens) that's identical for all users.
  • Before OpenClaw became virally popular, this worked fine — same prefix = same hash = cache hit.
  • Now that OpenClaw has many users, the total API volume from all users is too large for a single machine.
  • Requests from OpenClaw users are therefore spread across multiple machines randomly. Two requests from the same user are unlikely to be routed to the same machine.
  • Result: Cache hit on system prompt, cache miss on everything user-specific

Cost impact: ~5x higher than necessary, since the vast majority of tokens could have been cache read tokens but instead become input tokens.

Potential solution (A)

Related issue: #16357

If each user configures the prompt cache key to a unique value, the problem will be solved, at least for providers that support prompt cache key.

The sane default would be an automatically generated random value that's unique per installation, or maybe even per agent.

It's not confirmed whether this would solve the issue for all providers, but it's conceivable that some provider might support caching without supporting a cache key parameter.

Beyond the uncertaintly of how completely this would solve the problem, it's also more brittle/complex than proposed solution (B) below.

Better solution (B)

Change the system prompt generation to make the first line different from that of other users, with a high probability.

Morally, that could be as easy as:

modified   src/agents/system-prompt.ts
@@ -393,13 +393,15 @@ export function buildAgentSystemPrompt(params: {
   });
   const workspaceNotes = (params.workspaceNotes ?? []).map((note) => note.trim()).filter(Boolean);
 
+  const first_line = `You are ${current_agent.name || current_agent.id}, a personal assistant running inside OpenClaw.`;
+
   // For "none" mode, return just the basic identity line
   if (promptMode === "none") {
-    return "You are a personal assistant running inside OpenClaw.";
+    return first_line;
   }
 
   const lines = [
-    "You are a personal assistant running inside OpenClaw.",
+    first_line,
     "",
     "## Tooling",
     "Tool availability (filtered by policy):",

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions