Semantic Caching
Cache on meaning, not spelling
Semantic caching keys replies by meaning, not exact text: a near-duplicate question reuses the stored answer when embedding similarity clears a threshold. It saves on repetitive-but-not-identical traffic at the price of a distance computation and collision risk.
What you will learn
- Key a cache by embedding distance
- Tune a similarity threshold with a collision test
- Decide when semantic beats exact caching
What is this?
A semantic cache embeds each request, then compares it to stored request embeddings. If cosine similarity exceeds a threshold, the stored response is returned as a 'good-enough' match — even when the wording differs. You trade a small chance of mismatch for much higher hit rates.
Why do you need it?
- Users ask the same thing many ways: 'refund policy', 'can I get a refund', 'how do refunds work'.
- Exact-match keys miss all of those; semantic keys catch the family.
- One embedding lookup (~ms) beats a 1-2s model call whenever it converts a miss to a hit.
Mental model
Semantic cache
A librarian's fuzzy recall
'The tall building book' still gets you 'Skyscrapers: A Visual History' — the librarian matches meaning, not exact titles.
How it works
- Embed the request; compare against a stored list of prior request embeddings.
- If max cosine ≥ threshold, return that entry's answer.
- On miss, embed-save answer, respecting TTL and capacity.
- Threshold picking is a collision test: too low returns wrong answers.
Similarity gate.
Examples
A similarity check
import numpy as np def cosine(a, b): return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))) q = embed("how do refunds work")stored = [{"q": embed("refund policy"), "a": "..."}]best = max((cosine(q, e["q"]), e) for e in stored)hit = best[0] >= 0.92print("hit" if hit else "miss", round(best[0], 3))Crossing the gate serves the stored answer; beneath it the model runs again.
In production
- A customer FAQ answers near-duplicates from one cache entry, hitting 70%+.
- A code helper reuses similar-snippet answers, cutting burn on repeated themes.
- A lead-generation bot caches common intent clusters instead of every phrasing.
Best practices
- Set the threshold high initially (0.9+) and lower it with measured collisions.
- Store (request_embedding, answer) pairs, not just answers.
- Combine with exact-key first: exact hits are free and perfectly safe.
- Sample collisions periodically — sample real traffic to tune.
Common mistakes
- Threshold too low → wrong answers presented confidently.
- Storing stale answers under near-duplicates forever (no TTL).
- Forgetting the model/params in the key semantics.
Debugging tips
- Wrong matches when threshold passes → lower... no, RAISE the threshold or split the corpus by intent.
- Hit rate flat vs exact cache → your traffic has no near-duplicates; revert to exact.
- Slowness from scanning many vectors → index the embedding store or cap candidates.
Interview checkpoint
Hands-on lab
- Represent requests with normalized keyword vectors
- Compute cosine similarity between requests
- Serve near-duplicates above a threshold
Gate a Cache by Similarity
35 min · intermediate
Quick quiz
Semantic caching decides a hit using what?
Lowering the similarity threshold always raises hit rate safely.