Skip to content

Caching

Two distinct caches. Users search “caching” and land here, so this page distinguishes them.

For Anthropic models, CodeBuddy uses Anthropic prompt caching to avoid paying full input-token cost on repeat context. When the same system prompt + early messages are seen twice, the second call reads cached tokens at a fraction of the write price.

  • Cache hit rate on turn 2+ of a conversation: 99.3–99.98% measured 2026-07-10.
  • Applied via anthropicPromptCachingMiddleware in the deepagents pipeline; nothing to configure.
  • Costs tracked per bucket (input / cache_read / cache_creation / output) in CostTrackingService — see Cost tracking.

Turn 1 in each session writes the cache; every following turn hits the cache prefix. Bailout only if the system prompt changes mid-conversation (rare — the prompt is built once at agent construction).

Other providers don’t currently participate in provider-side caching.

2. In-process multi-tier cache (EnhancedCacheManager)

Section titled “2. In-process multi-tier cache (EnhancedCacheManager)”

Local cache the extension uses to skip redundant vector-DB work, LLM responses, and file-metadata computation. Independent from provider-side caching.

TierKeyValueDefault TTLPurpose
EmbeddingFile content hashnumber[]1 hrSkip re-embedding unchanged files
SearchQuery hashSearch results1 hrAvoid duplicate vector-DB lookups
MetadataFile pathFile metadata1 hrCache stats, language detection
ResponsePrompt hashstring1 hrCache LLM responses for identical prompts

Each tier is its own Map<string, CacheEntry<T>> — no shared eviction pressure.

interface CacheEntry<T> {
data: T;
timestamp: number; // Created-at
accessCount: number; // For LFU
lastAccessed: number; // For LRU
ttl: number; // ms
size: number; // Estimated bytes
}

Three policies, one per instance:

PolicyBehaviorBest for
LRUDrop least recently accessed. Default.General use
LFUDrop least frequently accessed.Hot-path repeat queries
TTLDrop oldest by creation timestamp.Time-sensitive data
interface CacheConfig {
maxSize: number; // entries per tier (default 10 000)
defaultTtl: number; // ms (default 1 hr)
maxMemoryMB: number; // memory ceiling (default 100 MB)
cleanupInterval: number; // sweep timer (default 5 min)
evictionPolicy: "LRU" | "LFU" | "TTL"; // default LRU
}

Every 5 min:

  1. TTL pass — remove entries where now > timestamp + ttl.
  2. Memory pass — if total > maxMemoryMB, evict by policy until under.

getStats() returns hitCount, missCount, size, maxSize, memoryUsage, avgAccessTime, evictionCount. Reported to the Performance Profiler when connected.

Multiple caches with different configs coexist:

const vectorCache = new EnhancedCacheManager(
{ maxSize: 10000, maxMemoryMB: 100, evictionPolicy: "LRU" },
profiler,
"vector-db",
);
const responseCache = new EnhancedCacheManager(
{ maxSize: 1000, maxMemoryMB: 20, evictionPolicy: "TTL" },
profiler,
"responses",
);

Each logs under a prefixed name (EnhancedCacheManager:vector-db).

ConsumerTiers usedPurpose
VectorDBServiceEmbedding + SearchSkip re-embedding, cache search results
ContextRetrieverSearch + MetadataCache semantic search results
EnhancedPromptBuilderResponseCache identical prompt responses
CodebaseAnalysisWorkerMetadataCache file language detection

Entry size is estimated by JSON-serializing the value and measuring bytes — an upper-bound approximation. For embeddings (number[]), size is roughly dimensions × 8 bytes (64-bit floats) plus array overhead.

Implements vscode.Disposable. On dispose: cleanup timer cleared, tier maps cleared, stats reset. Prevents leaks on extension reload.