15-20% of Your LLM Requests Are Duplicates. You're Paying for All of Them.
The Pattern That Wastes 15-20%
Duplicate requests show up in predictable places: a user refreshing a page that re-triggers a summarization call, a retry after a flaky network response, multiple users asking the same FAQ-style question, or a background job re-processing the same record because a previous run wasn't marked complete. None of these need a fresh model call — the answer was already computed, sometimes seconds earlier. Without a caching layer, every one of them goes straight back to the model and gets billed again.
Interactive: Caching ROI Calculator
Estimate your caching ROI
Three Cache Levels
Not every duplicate is the same kind of duplicate, and they need different caching strategies. A deterministic cache handles requests where the exact same input should always produce the exact same output — classification, lookups, structured extraction with temperature 0. A semantic cache handles requests that are worded differently but mean the same thing, using embedding similarity to match against recent answers. A session-scoped cache plus a longer-lived persistent cache handle conversational context — the same user asking a related follow-up, or the same document being summarized again days later.
Interactive: Cache Strategy Decision Tree
Click a strategy
The Visibility Problem
You can't fix duplicate waste you can't see. Most teams only discover their duplicate rate after instrumenting every request with enough metadata to compare them — input hash, feature name, user or session ID, and timestamp. Per-request tracking turns "we probably have some duplicate calls" into "feature X has a 22% duplicate rate and costs $1,400/month in repeated calls," which is the difference between a guess and a fix.
// Hash the normalized input and check cache before calling the model
const key = hashInput(normalizedPrompt)
const cached = await cache.get(key)
if (cached) return cached
const response = await callModel(normalizedPrompt)
await cache.set(key, response, { ttlSeconds: 600 })
fetch('https://llm-track.com/api/ingest', {
method: 'POST',
headers: { 'x-api-key': process.env.LLMTRACK_KEY },
body: JSON.stringify({
provider: 'openai',
model: response.model,
feature: 'summarizer',
total_tokens: response.usage.total_tokens,
latency_ms: Date.now() - startedAt,
status: 'success',
cache_hit: false
})
}).catch(() => {})
Instrument first, then add the cache layer that matches your actual duplicate pattern.
FAQ
Deterministic and short-TTL caching are low risk. Semantic caching needs a similarity threshold tuned against real traffic before trusting it broadly.
It depends on how often the underlying data changes — minutes for live data, hours or days for stable reference content.
Log an input hash on every request for a week. The duplicate rate that surfaces will tell you which cache level to build first.
See your real duplicate rate — using your own request data
Start free. One async call. No proxy and no credit card required.
Start free →