Back to the blog
post.md

Practical guide to caching AI responses and searches

Understand prompt caching, exact-match caching, semantic caching, and caching in RAG to reduce cost and latency without reusing incorrect or stale answers.

AILLMCachingPrompt cachingSemantic cachingRAGEmbeddingsRetrieval

A cache hit does not mean the answer is correct. Caching only helps when the application knows what it can reuse, for how long, and within which boundaries.

The same question should not cost the full pipeline again

In previous guides, we covered RAG, chunking, embeddings, retrieval, structured outputs, evals, observability, and security. Once those layers are in place, a natural question appears: how can we avoid repeating the same search and generation every time?

Caching can reduce calls, tokens, and response time. In AI applications, however, it is not merely a performance decision. It is a consistency policy: the system needs to know when an earlier result is still valid and when it must return to the source, search layer, or model.

A fast answer can still be wrong

Imagine an assistant that answers questions about technical documentation. Someone asks how to configure a worker timeout. The system searches documents, builds context, calls the model, validates the output, and returns an answer. If the same question appears again shortly after, repeating the entire pipeline may be wasteful.

Now imagine that the documentation changed, the second person cannot access the document used earlier, or the first answer was created with a different prompt version and output format. Returning the earlier result is still fast and inexpensive, but it may be incorrect. The cache key needs to represent the context that makes the answer valid.

Caching is not a single mechanism

  • Prompt or context caching reuses the processing of a stable prefix, but the model still generates a new answer.
  • Exact-match caching returns a ready answer when it finds the same valid key.
  • Semantic caching looks for questions with similar meaning and tries to reuse a previous answer.
  • Embedding caching avoids recomputing the vector for the same text with the same model and preprocessing.
  • Retrieval caching reuses documents, IDs, or chunks returned by a search.
  • HTTP or CDN caching can store an endpoint response as long as private content and request variations are controlled.
Layered flow showing exact-match caching, semantic caching, retrieval, prompt caching, and the model call in an AI application.
Each layer avoids different work; the choice depends on what repeats and how long the result remains valid.

A five-question mental model

  1. Repetition: which work is happening again?
  2. Validity: how long does the result remain correct?
  3. Boundaries: for whom and in which context is it valid?
  4. Layer: which cache avoids only the repeated work?
  5. Measurement: how will you detect savings, staleness, and false hits?

Without observing repetition, caching becomes intuition-driven optimization. Without defining validity, TTL becomes an arbitrary number. Without tenant, user, language, and permission boundaries, the application may share an answer that should never cross that context.

Prompt caching is not response caching

With prompt caching, the application still requests a generation. The gain comes from reusing a stable part of the input, such as instructions, examples, tools, documents, or the start of a conversation. The new portion still needs processing, and the model still produces an output.

prompt-cache-vs-response-cache.txttext
1prompt cache2  stable prefix + new question3  -> model generates a new answer45response cache6  valid key found7  -> ready answer

OpenAI, Anthropic, and Google document their own mechanisms for reusing context. They differ in support, retention, limits, and usage reporting, and those details change across APIs and models. The more durable principle is to keep large, stable content first, dynamic content later, and measure what was actually reused.

Start with exact-match caching when it solves the problem

Semantic caching looks more intelligent, but it also creates a new class of error. When the application receives identical inputs and can build a complete key, exact-match caching is usually more predictable and easier to test.

Even then, the question alone rarely represents everything. Validity may depend on organization, language, access, environment, documentation version, prompt, model, tools, schema, and safety rules.

cache-key.txttext
1tenant:locale:permissionScope:knowledgeBaseVersion:promptVersion:model:responseSchema:normalizedQuestion23acme:en:developer:docs-v42:support-v3:model-a:answer-v2:how-do-i-configure-the-worker-timeout

The real key can be serialized and hashed. What matters is the reasoning: if `docs-v42` becomes `docs-v43`, the application starts looking for a different entry. Older answers can expire later without blocking publication of the new documentation.

Normalizing the question changes the definition of equality

Removing duplicate spaces, normalizing case, and serializing filters consistently can increase exact hits. Aggressive normalization, however, can erase important details. If numbers are removed, questions about 30-second and 300-second timeouts may become the same key.

Exact-match caching still depends on a correct definition of equality.

Semantic caching: more hits, more responsibility

With semantic caching, the application embeds the new question and searches for a previous entry that is close enough. If similarity passes the threshold and mandatory filters match, the answer may be reused.

  • A loose threshold can serve answers for different intents.
  • An overly strict threshold turns almost everything into a miss.
  • Tenant, language, version, and safety filters need to be hard boundaries.
  • The eval set needs both positive paraphrases and difficult negative cases.
semantic-cache-cases.txttext
1expected positive:2Where do I change the worker time limit?34hard negative:5What is the current worker timeout in production?

The questions are close in topic but do not ask for the same thing. The first seeks an instruction. The second asks for current state that may be dynamic and restricted. Similarity does not replace intent, context, or authorization.

Where caching fits into a RAG pipeline

rag-cache-layers.txttext
1question2  -> query embedding3  -> search and filters4  -> retrieved chunks5  -> prompt assembly6  -> model7  -> answer

Caching the embedding avoids recomputing the vector, but search and generation continue. Caching retrieval avoids repeating search and filters, but the model still answers. Caching the final answer may skip almost the entire pipeline, but it also carries the greatest risk of hiding source changes.

A retrieval cache key needs to consider the embedding model, index version, filters, permissions, and relevant search parameters. In a dynamic pipeline, prompt caching over retrieved context only helps when that prefix actually repeats.

TTL answers time; invalidation answers change

TTL answers how long an entry may be reused. Event-driven invalidation answers what changed and made the entry stale. A short TTL limits age; a version in the key separates new and old content; invalidation removes or makes answers inaccessible when a document, permission, or rule changes.

  • A document is published, updated, or removed.
  • An index is rebuilt or the embedding model changes.
  • A permission or access group changes.
  • The prompt, model, tools, or schema change.
  • A safety policy is revised.

The cache needs to be disposable and rebuildable. The source of truth remains outside it.

Permission is not a minor cache-key detail

Checking authorization only before writing is not enough. Reads also need to respect current access. An answer may have been created legitimately and remain stored after permission changes. If the value is returned before verification, the cache becomes a shortcut around authorization.

  • Separate namespaces by tenant when necessary.
  • Include access scope in the key or mandatory filters.
  • Revalidate authorization on reads in private flows.
  • Invalidate affected entries when permissions change.

Response caching does not replace idempotency

A feature that answers is different from a tool that changes state. If an agent receives a request to create a task, returning `task created` from cache does not prove the current action happened. Re-executing without considering idempotency, authorization, confirmation, auditing, and current state is not safe either.

A text cache must not pretend an operation happened. A similar request must not reuse the side effect of another execution.

How to validate whether it worked

  • Performance: hit and miss rates by layer, plus separate p50 and p95 latency for hits and misses.
  • Cost: calls and tokens avoided, together with added read, write, embedding, and storage costs.
  • Correctness: answer age, semantic false hits, and version, language, tenant, or environment mismatches.
  • Security: answers used after permission changes and authorization failures.
  • Quality: human or automated evaluation of a sample of hits.
  • Operations: the layer and reason for a hit, versions used, and the ability to disable caching.

A high hit rate is not enough. If the system reuses stale or semantically incorrect answers, the metric is celebrating the problem. Savings and quality need to appear in the same analysis.

When not to use caching

  • Traffic is low and there is almost no repetition.
  • The answer changes in real time or depends heavily on the user.
  • The application cannot represent permissions safely.
  • The source changes frequently and there is no invalidation strategy.
  • The operational cost of caching exceeds the work it avoids.
  • The team cannot yet measure semantic false hits.
  • The domain is high risk and a stale answer could cause harm.
  • The workflow performs actions with side effects.

How to start simple

  1. Measure which inputs, prefixes, or searches actually repeat.
  2. Choose a single layer to test.
  3. Start with exact-match caching when it solves the problem.
  4. Build a key that represents context, versions, and boundaries.
  5. Use a conservative TTL and define invalidation events.
  6. Record hits, misses, age, layer, and reason.
  7. Compare latency and cost before and after.
  8. Review a sample of reused answers.
  9. Add semantic caching only with positive and negative eval cases.

Closing thoughts

Good caching avoids repeated work. Bad caching repeats errors faster. The decision does not begin with Redis, a CDN, or the switch that enables prompt caching. It begins by understanding the workflow: what repeats, how long it remains valid, who it is valid for, which layer should act, and how a false hit will be detected.

Once those answers are clear, caching stops being a generic shortcut for reducing cost. It becomes an architecture decision that balances performance, consistency, security, and quality.