SDK consumers cannot control prompt cache segmentation

Resolved 💬 2 comments Opened Mar 8, 2026 by IDLEcreative Closed Apr 6, 2026

Problem

When using the Claude Agent SDK's query() function with a custom systemPrompt, there is no documented way to control how the prompt is cached. The SDK accepts systemPrompt as a plain string, but internally it has a sophisticated multi-segment caching system that SDK consumers cannot leverage.

What we discovered

By reading the SDK source, we found:

  1. __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ — an undocumented sentinel string that, when present in the system prompt, splits it into a stable prefix (cacheScope: "global") and a dynamic suffix (cacheScope: null). This is powerful but not documented anywhere in the SDK types or README.
  1. context-management beta overrides the boundary — when context-management-2025-06-27 is active (which is the default), the boundary marker is ignored (skipGlobalCacheForSystemPrompt = true) and everything falls back to cacheScope: "org". These two features are mutually exclusive for system prompt caching, but this isn't documented.
  1. CLAUDE_CODE_FORCE_GLOBAL_CACHE=true — required env var to activate the boundary split, but only works when context-management is OFF. Also undocumented.
  1. promptCache1hAllowlist — 1-hour cache TTL is gated by a server-side feature flag (tengu_prompt_cache_1h_config), so SDK consumers always get 5-minute TTL regardless of how stable their prompt prefix is.

Impact

Our use case: we build a business AI agent with a ~50K token system prompt composed of:

  • Stable prefix (~45K tokens): Base instructions + per-org OmniOS documents (change rarely)
  • Dynamic suffix (~3K tokens): Task state, recent messages, memory context (change every turn)

Without cache segmentation, every small change in the dynamic suffix invalidates the entire 50K token cache. Our measured cache write:read cost ratio is 6-12x (paying $6-12 to write cache for every $1 of reads), meaning the cache is being invalidated far more often than it's reused.

Requested changes

  1. Document __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ in the SDK types/README so consumers know it exists and how to use it.
  1. Document the interaction with context-management — that they're mutually exclusive for system prompt caching, and guidance on when to use which.
  1. Consider a structured systemPrompt option that accepts cache segments explicitly:

``typescript
systemPrompt: {
sections: [
{ text: stablePrefix, cache: 'global' }, // Long-lived, shared across sessions
{ text: dynamicSuffix, cache: 'ephemeral' } // Short-lived, per-turn
]
}
``

  1. Allow SDK consumers to opt into 1h cache TTL for stable prompt sections, rather than gating it behind a server-side allowlist.

Environment

  • @anthropic-ai/claude-agent-sdk (latest)
  • Using query() with custom systemPrompt string
  • Model: claude-sonnet-4-6
  • Beta features: context-1m, context-management, compact, code-execution-web-tools

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗