Caching AI Responses

Skip repeat AI calls by caching answers by prompt and deduplicating requests already in flight.

TL;DR

  1. Key each answer by its prompt and reuse the result.
  2. Deduplicate requests already inFlight for the same key.
  3. Persist a response cache across renders and sessions.

Cache by Prompt Key

    Build a Key

    Normalize the prompt into a stable key.

    const key = prompt.trim().toLowerCase();
    Check First

    Return a cached answer before calling.

    if (cache.has(key)) return cache.get(key);
    Store the Answer

    Save the result for next time.

    cache.set(key, text);

Deduplicate In-Flight

    Track Promises

    Cache the pending promise, not just the value.

    if (inFlight.has(key))
      return inFlight.get(key);
    Share One Call

    Both callers await the same request.

    const p = callModel(prompt);
    inFlight.set(key, p);
    Clean Up

    Drop the promise once it settles.

    p.finally(() => inFlight.delete(key));

Use React Query

    useQuery

    Cache and dedupe with a single hook.

    const { data } = useQuery({
      queryKey: ['ai', prompt],
      queryFn: () => ask(prompt),
    });
    Stable Key

    The queryKey identifies the cached entry.

    queryKey: ['ai', prompt]
    Set Freshness

    staleTime keeps answers cached longer.

    staleTime: 60_000

Persist Results

    Module Cache

    A Map outside components survives remounts.

    const cache = new Map<string, string>();
    Local Storage

    Persist stable answers across reloads.

    localStorage.setItem(key, text);
    Server Cache

    Cache in the route to share across users.

    // route-level cache = 1 call for all

Tips

  1. Reach for React Query or SWR; they cache by key, dedupe in-flight requests, and return the cached answer instantly on repeat.
  2. Normalize the cacheKey by trimming, lowercasing, and sorting options so equivalent prompts hit one entry instead of missing.

Warnings

  1. Do not cache personalized or fast-changing answers forever; set a staleTime so results refresh when they should.
  2. A cache in a component's state dies on unmount; use a module store, React Query, or storage to keep it across mounts.

In Practice

FAQ