Large language model requests are expensive compared with ordinary cache lookups. When users repeatedly ask questions with slightly different wording, an exact string cache misses even though the intended answer may be identical.

A semantic cache uses vector similarity to decide whether a new request is close enough to a previous request that its answer can be reused. The idea is attractive, but the difficult part is not storing embeddings. It is deciding when reuse is actually safe.

Start with a narrow cacheable surface

Do not make every model request eligible for semantic caching. Begin with requests whose answers are stable for a meaningful period, such as explanations of internal product concepts, documentation questions over a fixed corpus, or deterministic transformations.

Avoid caching requests that depend on rapidly changing data, user-specific permissions, hidden session state, or one-time actions.

A useful rule is: if two users ask semantically equivalent questions, should they receive the same answer at the same moment? If the answer is no, the cache key needs more context or the request should not be cached.

Build the cache key from behavior-changing inputs

The natural-language query is only part of the request. Model behavior can also depend on:

  • the system prompt or policy version;
  • model family or deployment configuration;
  • retrieval corpus version;
  • locale;
  • authorization scope;
  • output format or schema;
  • feature flags that alter prompting.

Treat these values as dimensions of the cache namespace.

namespace = hash(
  prompt_version,
  corpus_version,
  model_profile,
  locale,
  authorization_scope
)

Similarity searches should happen only inside a compatible namespace. Otherwise a highly similar question can retrieve an answer produced under different rules.

Use similarity as a gate, not a guarantee

Embedding similarity measures closeness in representation space. It does not prove that two requests have the same intent.

For example, these prompts share many words but require different answers:

How do I enable deletion protection?
How do I disable deletion protection?

A semantic cache therefore needs a conservative threshold and good evaluation data. Higher thresholds reduce false hits but also reduce savings.

Measure the cost of both error types:

  • false miss: an unnecessary model call;
  • false hit: a wrong or stale answer served confidently.

For most user-facing systems, false hits are much more expensive.

Store enough metadata to validate a hit

A cache entry should contain more than an embedding and response text. Useful metadata includes:

{
  "prompt_version": "support-v4",
  "corpus_version": "docs-2026-09",
  "created_at": "2026-09-02T00:00:00Z",
  "expires_at": "2026-09-09T00:00:00Z",
  "source_ids": ["account-security", "billing-basics"]
}

On a candidate hit, validate the metadata before returning the answer. If any required source or policy version has changed, treat it as a miss.

Separate lookup similarity from freshness

Similarity and freshness solve different problems.

Similarity asks whether the new request resembles a previous request. Freshness asks whether the previous answer is still valid.

Use explicit expiration for time-sensitive knowledge. For retrieval-backed systems, corpus-version invalidation is often stronger than time-to-live alone because an answer can become stale immediately after documentation changes.

A practical policy is to combine both:

  1. require a compatible namespace;
  2. require similarity above the threshold;
  3. require an unexpired entry;
  4. require unchanged source or corpus versions.

Avoid caching private context by accident

Semantic caches can leak information if responses produced with one user’s private context are reused for another user.

Do not put privileged and public responses in the same namespace. If an answer depends on account data, tenant data, or access-controlled retrieval, either disable semantic caching or include an authorization boundary in the key.

Never store secrets or raw credentials in cache metadata. Cache inputs should be sanitized according to the same data-handling rules used for model logging.

Evaluate with realistic near-duplicates

A cache threshold should come from examples, not intuition.

Build an evaluation set containing:

  • paraphrases that should reuse an answer;
  • similar-looking questions that should not;
  • negations;
  • requests differing by product, region, or account type;
  • old and new versions of questions after documentation changes.

For each candidate threshold, measure hit rate and incorrect-hit rate. Review false hits manually because they reveal the kinds of distinctions the embedding model is collapsing.

Observe the cache in production

Track at least:

  • semantic cache hit rate;
  • exact cache hit rate, if both exist;
  • similarity score distribution;
  • model calls avoided;
  • estimated latency and cost saved;
  • invalidations by reason;
  • sampled false-hit reports.

A rising hit rate is not automatically good. If the threshold was accidentally lowered, the hit rate can improve while answer quality gets worse.

Prefer deterministic reuse when possible

Semantic caching should not replace simpler cache strategies. Exact keys are easier to reason about and should be used when requests can be normalized deterministically.

For example, a structured request such as:

{"operation":"explain_error","code":"E1042","locale":"en"}

is better served by an exact cache key than by embedding the JSON and searching approximately.

Use semantic matching only where paraphrase tolerance creates meaningful value.

Common pitfalls

One global similarity threshold

Different request classes have different ambiguity. A threshold that works for FAQ questions may be unsafe for configuration commands.

Ignoring prompt changes

If the system prompt changes behavior, old responses may no longer satisfy the new policy. Version the prompt namespace.

Caching generated citations without source validation

A cached answer can retain references to documents that have moved or changed. Store source identifiers and invalidate when the corpus changes.

Treating cache hits as invisible

Include enough telemetry to identify whether an answer came from the model or the semantic cache. Debugging becomes much harder when the serving path is unknown.

A conservative rollout strategy

Start with a read-only, stable request class. Collect candidate semantic matches without serving them, then compare the cached answer with a fresh model answer. Use those results to choose a threshold and discover dangerous near-duplicates.

After enabling serving, keep a strict invalidation policy and monitor false hits. Semantic caching is most useful when it saves repeat work without changing user-visible correctness. The safest systems treat similarity as one signal inside a broader compatibility check rather than as permission to reuse any nearby answer.