arrow_backAI Engineering / LLM Caching
Level: Expert Updated: August 2026

LLM Caching

One of the simplest ways to save a lot of money and speed up responses: don't pay twice for the same computation. Three types of caching and when to use each.

Why caching matters

Every LLM call costs money (by tokens) and time. But a large share of calls repeats — the same long system prompt, the same fixed context, or even the same question asked again and again. Caching means: compute once, reuse. The result — cost savings (sometimes tens of percent) and much faster responses.

savings
In short

3 types: Prompt caching (the fixed part of the prompt), Semantic caching (similar questions), and Exact-match (identical questions). Each for a different scenario.

1. Prompt Caching (Context Caching)

Leading LLM providers let you cache the fixed, long part of the prompt — the system prompt, instructions, a context document that recurs on every call. On subsequent calls, that part isn't recomputed and is billed at a fraction of the price.

When it's gold: a chatbot with a long system prompt, RAG with a fixed document, or an agent that sends the same instructions repeatedly. Example with Anthropic:

import anthropic
client = anthropic.Anthropic()

resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_SYSTEM_PROMPT,          # instructions + fixed context
        "cache_control": {"type": "ephemeral"}  # mark for caching
    }],
    messages=[{"role": "user", "content": user_question}],
)
# the first call builds the cache; the following ones use it and are much cheaper

2. Semantic Caching

Here you save the entire call: if a question similar in meaning was already answered — return the cached answer without calling the LLM at all. You use embeddings: compute a vector for the question, search the cache for a question with cosine similarity above a threshold, and if found — return it.

def semantic_cache_get(question, cache, threshold=0.92):
    q_vec = embed(question)
    for entry in cache:                 # in production: a vector DB, not a loop
        if cosine(q_vec, entry["vec"]) >= threshold:
            return entry["answer"]      # cache hit — no LLM call
    return None

answer = semantic_cache_get(q, cache)
if answer is None:
    answer = call_llm(q)                # cache miss
    cache.append({"vec": embed(q), "answer": answer, "q": q})

3. Exact-match Caching

The simplest: the cache key = a hash of the full input (prompt + parameters). If exactly the same input recurs — return the stored output. Fast and cheap, but only catches exact repeats. Good for deterministic tasks (temperature 0) that recur exactly.

import hashlib, json
def key(payload): return hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()

k = key({"model":"gpt-5.6","temp":0,"prompt":prompt})
if k in store: return store[k]
out = call_llm(prompt); store[k] = out; return out

Cache invalidation

A stale cache = wrong answers. Manage it:

Common mistakes

rocket_launch

Next step

Caching is part of broader cost control. Combine it with model routing and smart pricing.