Concepts / Cache Implementation

Cache Implementation

Exact caching reuses a stored result only when the exact same item is requested, so the lookup key must match precisely.

  • Programming

The Cost of Answering the Same Request Twice

Imagine an AI application that receives the same kind of question many times a minute. Each time, it may call a model, run a multi-step reasoning process, search a vector index, or query a database. Some of these actions are slow, and some cost money to run. If the application has already produced an answer for a request, running the whole process again is wasted effort. Exact caching avoids that waste by keeping a record of past results and reusing them when the same request comes back.

This article follows one question from start to finish: when the system receives a request, how does it decide whether a stored result can be used, and what has to be true before that reuse is safe? The answer depends on the word exact, so we start there.

What do you think happens?

A cache already holds a stored summary for the product 'Alpha'. A new request asks for a summary of 'Alpha Pro', a product whose name sounds nearly identical. Does the cache return the stored Alpha summary?

  • Yes, because the names are almost the same

  • No, because the request does not match the stored key exactly

Reveal answer
Answer:

No. The request is a miss, and the system has to create a summary for Alpha Pro.

Exact caching reuses a stored result only when the exact same item is requested. A summary of one product cannot be handed back for a different product, even when the two sound alike. The lookup key is the request itself, so only an identical key produces a hit.

Watching the Cache Change Over Requests

The source describes a concrete case: a user asks a model to summarize a product. Before doing any work, the system checks whether a summary of this exact product already exists. If it does, the stored summary is fetched, which is a hit. If it does not, the system creates the summary and stores it for next time, which is a miss. The best way to understand this logic is to watch the contents of the cache change across a short run of requests.

Request 1: Alphamiss, stores AlphaRequest 2: Betamiss, cache holds Alpha andBetaRequest 3: Alphahit, returns stored AlphaRequest 4: Alpha Promiss, cache adds Alpha ProRequest 5: Betahit, returns stored Betanext requestnext requestnext requestnext request
After each request in the sequence, what is stored in the cache, and which requests were hits and which were misses?
Worked example

Tracing hits and misses in a product-summary cache

The cache starts empty. Five summary requests arrive in this order: Alpha, Beta, Alpha, Alpha Pro, Beta. For each request, determine whether it is a hit or a miss, and state what the cache holds afterward.

  1. 1
    Request 1: Alpha

    The cache is empty, so no key matches. This is a miss. The system creates the Alpha summary and stores it under the key Alpha. Cache holds: Alpha.

  2. 2
    Request 2: Beta

    The key Beta is not in the cache. This is a miss. The Beta summary is created and stored. Cache holds: Alpha, Beta.

  3. 3
    Request 3: Alpha

    The key Alpha matches a stored entry exactly. This is a hit, so the stored Alpha summary is fetched and no new work is done. The cache does not change: Alpha, Beta.

  4. 4
    Request 4: Alpha Pro

    Alpha Pro is a different product from Alpha, so the exact key is not present. This is a miss even though the name looks similar. Cache holds: Alpha, Beta, Alpha Pro.

  5. 5
    Request 5: Beta

    The key Beta is stored, so this is a hit. The stored Beta summary is returned. Cache still holds: Alpha, Beta, Alpha Pro.

Result

Requests 3 and 5 are hits, and requests 1, 2, and 4 are misses. Only the misses did new work, and each miss added one entry. Hits reused existing entries without changing the cache.

Key point

Every miss adds an entry to the cache, and every hit leaves the cache unchanged. The cache grows only through misses, which is why the question of how big it may become matters later in this article.

Why the Match Has to Be Exact

Definition

Exact caching reuses a stored result only when the exact same item is requested, so the lookup key must match precisely. The lookup key is the request itself, and only an identical key produces a hit.

key: Alphastored Alpha summaryrequest: Alphaexact match, hitkey: Betastored Beta summaryrequest: Alpha ProMaxno identical key, misskey: Alpha Prostored Alpha Pro summaryidentical keynear match rejected
Which stored entry is returned for a given request, and why does a request that differs by one parameter get a miss?

Read the diagram as a lookup table. The request Alpha finds its stored value because the key matches exactly. The request Alpha Pro Max looks close to the stored key Alpha Pro, but it is not identical, so the cache does not return that entry. A near match is still a miss, because exact caching never reuses a result for a request that is merely similar.

The same pattern appears in embedding-based retrieval, which the source also names as a use of exact caching. When an incoming query is already in the vector search cache, the stored result is fetched. If it is not, a vector search runs for that query and its result is cached. In both cases the purpose is to avoid redundant work: repeating a search that has already been done for the same query.

Exact caching is most appealing for certain requests. The source highlights queries that involve multiple steps, such as chain-of-thought reasoning, and time-consuming actions such as retrieval, SQL execution, or web search. The more work a request requires, the more there is to save by reusing its answer.

Choosing Where the Cache Lives

An exact cache can be implemented with in-memory storage, which allows fast retrieval. The source notes a limit to this choice: in-memory storage is restricted in how much it can hold. Because of that limit, a cache can instead be built on a database such as PostgreSQL or Redis, or on tiered storage, which is used to balance speed against storage capacity.

Storage optionWhat it offersWhat it gives up
In-memory storageFast retrieval of stored resultsRestricted in how much it can hold
Database such as PostgreSQL or RedisA larger home for cached results when in-memory space runs shortReads are less fast than in-memory retrieval, since faster storage tends to hold less and larger storage tends to be slower to read
Tiered storageA balance between speed and storage capacityRequires a design decision about where results should live along the speed-capacity spectrum

Storage options for an exact cache, as described in the source

Reading this as a tradeoff helps. Faster storage tends to hold less, and larger storage tends to be slower to read. The cache design is a decision about where on that spectrum your results should live, given the volume of requests your application handles. A small volume of requests may fit comfortably in fast memory, while a high volume may push the design toward larger storage.

When the Cache Is Full

A cache that only ever grows will eventually cause a problem, especially when storage is limited. The source states that having an eviction policy is crucial for managing cache size and maintaining performance. An eviction policy is the rule the system uses to decide which entries to remove when space is needed.

The source names three common eviction policies. Least Recently Used (LRU) is one. Least Frequently Used (LFU) is another. First in, first out (FIFO) is the third. The names indicate what each policy looks at: LRU is concerned with how recently an entry was used, LFU with how often it was used, and FIFO with the order in which entries arrived. The source lists these names without describing their internal mechanics, so treat the names and what they track as the core facts to remember.

PolicyWhat it looks atEntry it is concerned with removing when space is needed
LRU (Least Recently Used)How recently an entry was usedThe entry that has gone longest without being used
LFU (Least Frequently Used)How often an entry was usedThe entry that has been used the fewest times
FIFO (First In, First Out)The order in which entries arrivedThe entry that arrived earliest

Common eviction policies named in the source, with the concern implied by each name

Key point

The three policies answer the same question, which entry to remove, but they answer it from different evidence: recency of use, frequency of use, or arrival order.

Requests That Should Bypass the Cache

Not every request is worth storing. The source says how long a query should stay in the cache depends on how likely that query is to be called again. Two categories are called out as poor candidates. The first is user-specific queries, such as a question about the status of one's recent order. That result is unlikely to be reused by other users, so it should not be cached. The second is time-sensitive queries, such as asking about the weather. A stored answer to a question whose correct answer changes over time becomes misleading, so caching it makes less sense.

User-specific?Time-sensitive?Likely to be reused?Check exact keyReturn stored resulthitBypass the cacherun the request freshCompute and storemissyesnoyesnonoyesexact key foundno exact key
For a given request, what decision path determines whether its result is safe to cache or must bypass the cache?

The flowchart turns the source's guidance into a sequence of questions. The first two questions screen out requests that are user-specific or time-sensitive. The third asks whether the request is likely to be called again, which the source describes as the factor that governs how long a query should stay in the cache. Only requests that pass all three checks reach the exact-key lookup. The source also notes that many teams train a classifier to predict whether a query should be cached. The source does not describe how such a classifier is built, so the important idea is the goal it serves: predicting the likelihood that a query will be reused.

Caching has a hazard beyond wasted storage. The source warns that caching, when not properly handled, can cause data leaks. Consider an ecommerce site where a user asks, 'What is the return policy for electronics products?' The question sounds the same for everyone, but in this case the return policy depends on the user's membership. To answer, the system first retrieves that user's information, then generates a response that contains it. If that response were cached under the generic question and then returned to a different user with the same question, the second user would receive an answer built from someone else's membership details.

Common Mistakes With Exact Caching

  • Common mistake

    Treating a near match as a hit

    What it looks like

    A request for Alpha Pro Max is served the stored Alpha Pro summary because the names are almost the same.

    Why it fails

    Exact caching reuses a stored result only when the exact same item is requested. A near match has a different lookup key.

    Do this instead

    Compare keys exactly. Only an identical key produces a hit; anything else is a miss.

  • Common mistake

    Caching every request by default

    What it looks like

    Weather questions and personal order-status questions are stored like any other query.

    Why it fails

    User-specific results are unlikely to be reused by others, and time-sensitive answers become misleading as the correct answer changes.

    Do this instead

    Screen requests first, bypassing the cache for user-specific or time-sensitive queries and for requests unlikely to be reused.

  • Common mistake

    Letting the cache grow without limit

    What it looks like

    Every miss adds an entry, and no entry is ever removed.

    Why it fails

    The source states that an eviction policy is crucial for managing cache size and maintaining performance.

    Do this instead

    Choose an eviction policy such as LRU, LFU, or FIFO to decide which entries to remove when space is needed.

  • Common mistake

    Assuming a generic-looking question has a generic answer

    What it looks like

    The return policy question is cached, and the membership-dependent answer is then served to other users.

    Why it fails

    The source warns that improper caching can leak data when the answer depends on who is asking.

    Do this instead

    Identify whether the response was built from user information before storing it.

  • Common mistake

    Choosing in-memory storage without considering its capacity limit

Trace It Yourself

MEDIUM

The cache starts empty. The following summary requests arrive in order: Gamma, Delta, Gamma, Gamma Plus, Delta, Gamma. For each request, state whether it is a hit or a miss, and list the keys the cache holds after the request. Then explain why the Gamma Plus request does not reuse the stored Gamma summary.

Hints
  • Start with an empty cache. The first time any key appears, the result must be a miss.
  • A hit leaves the cache unchanged, while a miss adds one new key.
  • Ask whether the key is identical to a stored key, not whether it sounds similar.

Key Takeaways

  • Exact caching reuses a stored result only when the exact same item is requested, so the lookup key must match precisely; similar-looking requests are misses.
  • Tracing a cache means applying one rule per request: a matching key is a hit and leaves the cache unchanged, while a miss does new work and adds an entry.
  • An exact cache can live in in-memory storage for speed, in a database such as PostgreSQL or Redis, or in tiered storage; each choice trades speed against capacity.
  • An eviction policy such as LRU, LFU, or FIFO decides which entry to remove when space is needed, based on recency of use, frequency of use, or arrival order.
  • User-specific and time-sensitive queries are poor candidates for caching, and careless caching of answers that depend on the asker can leak private information.

More concepts starting with C