KV Cache Deep Dive
How LLM Providers Cache Their Way to Speed (and Save You Money)
Jiuhe Wang | Apr 12, 2026 | ~12 min read
The Speed Secret Nobody Talks About
Every time you send a prompt to an LLM, there's a hidden hero working behind the scenes: KV Cache. It's the reason your second message in a long conversation is cheaper than the first one, the reason cached context feels "instant," and the reason providers can offer batch processing at lower costs.
But here's the thing — most people don't know how it actually works. They just know it saves tokens. This article fixes that. We'll look at the transformer architecture from an inference angle, trace exactly what happens token by token, and understand why KV cache is the reason your API bill isn't 10x higher.
Why Do We Even Need KV Cache?
Let's talk about the attention mechanism — the heart of every transformer model. When an LLM processes text, every token needs to "look at" every other token to understand context. This is called self-attention.
Here's the painful math: for a sequence of n tokens, computing attention is O(n2) in computation and memory. In autoregressive generation, we process n tokens during prompt filling, then generate token-by-token. Each generated token needs to attend to all n previous tokens.
Token 1: compute attention over 1 token
Token 2: recompute attention over 2 tokens
Token 3: recompute attention over 3 tokens
...and so on, each step starting from scratch
Token 1: compute and cache K/V
Token 2: retrieve cached + compute new
Token 3: retrieve cached + compute new
...cached values reused every step
Inside the Attention Mechanism
To understand KV cache, we first need to look at what K and V actually are. Every token in a transformer gets transformed into three vectors through learned linear projections:
"Hello"
"Hello"
"Hello"
The Attention Score Computation, Step by Step
The attention formula looks intimidating, but each piece has a clear meaning. Let's break it down:
Compare every token's Query with every token's Key. Result: an "attention score" for each pair — how much should token A pay attention to token B?
Scale down by the square root of the key dimension. Prevents the dot products from growing too large, which would make softmax produce extreme probabilities.
Convert scores into probabilities (all add to 1.0). A token might pay 40% attention to token A, 35% to B, 25% to C, etc.
Multiply the attention weights by the Value vectors. This produces a weighted "context" — each token's representation is now infused with meaning from all the tokens it attended to.
Hover cells to inspect. Each row shows how much a token (left) attends to each token (top). Diagonal = self-attention.
What Exactly Is KV Cache?
KV Cache is exactly what it sounds like: a cache that stores the Key and Value matrices for every token that's already been processed. Instead of recomputing K and V for all previous tokens during each generation step, we simply look them up from the cache.
The Two Phases of LLM Inference
The model processes the entire input prompt. For each token, it computes Q, K, and V vectors through all transformer layers. These K and V matrices are stored in the KV cache. This is a parallel computation — all tokens are processed at once.
The model generates tokens one at a time. For each new token, it computes Q (unique to this position) and reuses cached K/V from all previous positions. This is sequential — one token at a time.
The Speedup Numbers
Let's put numbers on this. For a 1000-token conversation where we generate 100 tokens:
| Scenario | K/V Computations | vs Baseline |
|---|---|---|
| No KV Cache (baseline) | 1000 + (100 × 1000) = 101,000 | 1x |
| With KV Cache | 1000 + (100 × 1) = 1,100 | ~92x faster! |
| Prompt Cached (reuse) | 0 + (100 × 1) = 100 | ~1000x faster! |
Step-by-Step Decoding with KV Cache
A tiny model processes a 5-token prompt and generates 4 tokens. We'll walk through every step — what gets computed, what gets read from cache, and how the cache grows.
Prefill (5 tokens: "The cat sat on mat") → Decode (4 tokens: "and purred happily.")
Phase 1: Prefill — Processing the Prompt
During prefill, the model processes all 5 input tokens in parallel. For each token at each layer, it computes Q, K, and V, then stores K and V in the cache.
| Token | Compute Q | Compute K, V | Store in Cache |
|---|---|---|---|
| T1 "The" | Q1 computed | K1, V1 computed | Cache += [K1, V1] |
| T2 "cat" | Q2 computed | K2, V2 computed | Cache += [K2, V2] |
| T3 "sat" | Q3 computed | K3, V3 computed | Cache += [K3, V3] |
| T4 "on" | Q4 computed | K4, V4 computed | Cache += [K4, V4] |
| T5 "mat" | Q5 computed | K5, V5 computed | Cache += [K5, V5] |
After prefill: the cache holds 5 KV pairs — one for each token. Now the decode phase begins.
After prefill, the cache contains: [K1, V1, K2, V2, K3, V3, K4, V4, K5, V5] — for all 5 tokens, for all layers.
Phase 2: Decode — Generating Token by Token
Now the model generates tokens one at a time. At each step, it reuses cached K/V and computes only the new token's Q. Here's what that looks like over 4 decode steps:
The model computes attention between the new token and all 5 cached tokens.
Cache now contains: 6 KV pairs (5 from prefill + 1 new)
Cache now holds 6 KV pairs. Model retrieves all of them.
Cache now contains: 7 KV pairs. Notice: K1 through K6 were not recomputed — just read from memory.
Same pattern. Cache grows by one more pair.
Cache now contains: 8 KV pairs
Final step. The model decides to stop.
Final cache: 9 KV pairs. The full sentence "The cat sat on mat and purred happily." is complete.
| Phase | Q Computed | K/V Computed | Cache Reads | Cache Writes |
|---|---|---|---|---|
| Prefill (5 tokens) | 5 | 5 | 0 | 5 |
| Decode (4 tokens) | 4 | 4 | 5+6+7+8 = 26 | 4 |
| Total | 9 | 9 | 26 | 9 |
Without KV cache, each decode step would recompute all K/V from scratch. That's 5 + 6 + 7 + 8 = 26 total K/V computations. With cache: only 9. That's 3x fewer K/V computations. As the generated sequence gets longer, the savings grow — at step 10 you'd be retrieving 14 KV pairs but computing only 1.
Multi-Layer Reality
Real LLMs have dozens of transformer layers. Each layer has its own K and V projections — meaning each layer maintains its own KV cache. For a 32-layer model, you actually have 64 KV caches running in parallel!
Each layer stores K/V for every token. For a 32-layer model with 8 tokens in context: 32 layers × 2 (K & V) × 8 tokens = 512 cache entries.
Real-World Example: A Multi-Turn Conversation
Let's trace a practical scenario: a user has a 5-message conversation with a coding assistant. We'll see how the KV cache evolves across messages and what it means for your wallet.
Decode: compute Q for 80 tokens, each retrieving 12..91 KV pairs from cache
Decode: retrieve up to 100 KV pairs (92 cached + 8 new) for each of the 40 decode steps
Savings: 12 tokens from Message 1 are cached! No recomputation needed.
Decode: each step retrieves up to 110 cached KV pairs
Savings: All 100 KV pairs from previous conversation are reused!
Total KV pairs after this message: 115
Each decode step in this message: retrieves 119 KV pairs from cache!
| Message | Input Tokens | Cached from History | New KV Computed | Cost (cached vs new) |
|---|---|---|---|---|
| Msg 1 (fibonacci) | 12 | 0 | 12 + 80 decode = 92 | Full price |
| Msg 2 (memoize) | 8 | 92 | 8 + 40 decode = 48 | ~50% cheaper |
| Msg 3 (decorator) | 10 | 100 | 10 + 60 decode = 70 | ~55% cheaper |
| Msg 4 (fib 30) | 5 | 110 | 5 + 20 decode = 25 | ~60% cheaper |
| Msg 5 (print) | 4 | 115 | 4 + 15 decode = 19 | ~65% cheaper |
By message 5, most of the work is already done. Those 115 cached KV pairs from earlier messages mean message 5's decode steps barely touch new computation. Compare that to sending message 5 as a standalone request with no history — you'd pay full price for everything.
Prefix Caching: The Next Level
Prefix caching extends session-level KV cache across multiple requests. Instead of caching within a single conversation, it caches based on the content of the prompt prefix. If two requests share the same system prompt or instruction prefix, they share the KV cache — no recomputation needed.
The Hash-Based Approach
Providers compute a cache key (usually a hash) from the prefix content. When a new request arrives, the system checks if any cached prefix matches. Matching bytes can reuse cached KV states — no recomputation needed.
What Gets Cached?
Different providers cache at different granularities:
| Cache Type | Cached Content | Savings |
|---|---|---|
| Session Cache | Same conversation thread | 50-90% on continuation |
| System Prompt Cache | Fixed system instructions | Per-request savings |
| Semantic Prefix | Common instruction patterns | Cross-request savings |
| Tool Definition Cache | Function schemas, RAG docs | Significant for tool-use |
The Memory Math: Why KV Cache Is Expensive
KV cache is brilliant for speed, but it's a memory monster. Every cached K/V vector consumes GPU VRAM. Let's calculate the real cost.
Here's what each piece of the formula means in plain terms:
The punchline: 2 × 80 × 8192 × 8192 × 2 bytes = ~21 GB for a single full-context sequence on Llama 3 70B.
Real-World Example: Llama 3 70B
= 32,768 bytes = ~32 KB per token per layer
= ~21 GB per sequence
Memory Optimization Techniques
How Different Providers Implement KV Cache
Every major LLM provider has their own KV cache implementation. Let's break down what each one offers:
cache_controlsKV Cache and Cost Optimization
This is where KV cache directly impacts your wallet. Understanding cache mechanics lets you structure prompts for maximum reuse.
Cache Hit = Massive Savings
Same prefix is reused
No matching prefix found
The Cache Temperature Model
Think of KV cache as having a "temperature" — how likely it is to hit:
Real Example: Agentic AI System
Consider an AI coding assistant with this prompt structure:
Practical Tips & Tricks
Maximizing Your Cache Hit Rate
Put static content first — system instructions, tool definitions, guidelines. Put dynamic content last. The longer the matching prefix, the more cache hits.
With OpenAI's explicit caching, wrap content in cache control markers. The provider will tell you exactly what's cached.
If you have multiple requests with similar prefixes (e.g., analyzing different files with the same instructions), batch them together or send them sequentially to leverage session caching.
Most providers expire session caches after 5-60 minutes of inactivity. If you're building a long-running agent, keep sessions alive or explicitly manage cache state.
Don't guess. Most providers return cache hit metadata in their API responses. Track this in your observability stack. A 70% cache hit rate on an agent making 10K requests/day = thousands of dollars saved.
The Complete Picture
Here's the KV cache lifecycle:
1. Prefill: Input tokens processed in parallel. K/V computed and cached for every token at every layer.
2. Decode: Each new token computes only Q — K and V are fetched from cache. Massive speedup.
3. Prefix Cache: If the same prefix appears in multiple requests, the K/V are shared across requests. Massive cost savings.
4. Memory: All that cached data lives in GPU VRAM. Cache size grows with sequence length and model size. Memory is the bottleneck.
5. Optimization: Providers use quantization, paging, and smart eviction to maximize cache efficiency. You just pay less.
Key Takeaways
- KV cache is why LLM inference doesn't take forever — without it, generating a 500-token response would require recomputing attention from scratch at every single step
- Session-level caching is automatic on most providers — keep a conversation going and the per-message cost drops fast
- Prefix caching is where providers compete now — OpenAI, Anthropic, and Google all want to be the one caching your system prompts
- Memory is the actual bottleneck — KV cache size scales with sequence length and model size. Every extra token in context is more GPU RAM eaten
- Prompt structure drives your cache hit rate — static content first, dynamic last, and your bill reflects it
- Groq for speed, OpenAI for features, Anthropic for quality, Gemini for long context — each has its own cache implementation
Now that you understand KV cache, you'll never look at your API bill the same way again.