KV Offloading
Plain Explanation
Serving large language models hits a wall when the GPU runs out of memory holding conversation history. Every new or resumed chat can force the model to re-encode long prompts, which is slow and blocks other users. That means great single-user speed but poor throughput once many users pile up.
KV offloading fixes this by treating the model’s attention memory like a tiered storage system. Picture a library desk (GPU) with only a few slots: the hottest books stay on the desk, others move to a nearby shelf (CPU) or a storeroom (NVMe). When a user resumes a session, the system fetches the needed pages instead of re-reading the whole book.
Mechanically, the Key/Value tensors produced during the prefill step are saved as blocks and managed across tiers. On a cache hit, the runtime loads those KV blocks back toward the GPU and skips recomputing the long-prompt attention. NVMe means fast SSD storage; HBM (High Bandwidth Memory) is the GPU's very fast local memory; and TTFT (time to first token) is the delay before the first generated token appears. KV offloading is not claiming that NVMe is faster than HBM. It helps when loading a previously saved block is cheaper than running the whole prefill step again.
Examples & Analogies
- Customer support platform with many long chats: An agent switches between dozens of tickets, each with lengthy history. With KV offloading, the server pulls cached attention blocks from CPU or NVMe when the agent returns to a thread, avoiding a full re-encode of the prior messages.
- Coding assistant for enterprise repos: Developers open large codebases and jump across files. KV offloading keeps prior context blocks in lower tiers so the assistant can answer follow-ups quickly without reprocessing long source files each time.
- Document review in legal workflows: Reviewers revisit 100+ page contracts across sessions. Instead of recomputing the entire document context, the system reloads stored KV blocks for the relevant sections, keeping latency stable as the working set grows.
At a Glance
| GPU-only KV cache | CPU offload | NVMe/storage offload | |
|---|---|---|---|
| Memory headroom | Lowest | Higher | Highest |
| Latency on hit | Fastest | Fast | Slowest |
| Prefill recompute avoided | Limited by HBM | Broader reuse | Broadest, multi-session |
| Best for | Few long sessions | Moderate concurrency | Fleet-scale, huge working sets |
| Operational notes | Simple, but capped | Needs CPU RAM mgmt | Needs SSD/NVMe I/O & policies |
Offloading trades some hit latency for much larger working sets, so throughput improves when the bottleneck is GPU memory rather than raw compute.
Where and Why It Matters
- vLLM Production Stack (LMCache): Moves large KV caches to CPU or disk so more cache hits are possible, increasing effective concurrency under fixed GPUs.
- NVIDIA Dynamo KVBM: Provides a unified KV block manager for vLLM or TensorRT-LLM, with knobs for CPU/disk block counts and policies like SSD lifespan protection.
- Remote persistent storage practice: Treating KV as a durable, orchestrated storage class enables multi-session, multi-node reuse after pod restarts and node failures.
- Throughput and TTFT improvements when long prompts dominate: Time-to-first-token can improve when cache hits replace full prefill. If hits are rare, the same disk path can simply add I/O latency.
- Operational observability: Cache hit rate, tier latency, PCIe or SSD bandwidth, eviction reasons, and per-tenant working sets determine whether offloading helps in production.
Common Misconceptions
- ❌ Myth: NVMe offloading is faster than keeping everything on GPU. → ✅ Reality: NVMe is much slower than HBM; the win comes from skipping prefill when there’s a cache hit.
- ❌ Myth: KV offloading always helps every workload. → ✅ Reality: It pays off when GPU KV memory is the bottleneck; for short prompts or single-user loads, it can add I/O latency with little benefit.
- ❌ Myth: You need proprietary hardware to deploy fleet-wide cache. → ✅ Reality: A software-defined tiered cache on standard servers and networks is shown to work and avoid lock-in.
How It Sounds in Conversation
- "We turned on CPU+NVMe KV offloading and our TTFT on 128K prompts dropped because we’re avoiding prefill on hits."
- "Let’s tune KVBM block counts via DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS before scaling replicas; we’re underusing RAM."
- "Enable the disk offload filter—we don’t want to burn SSDs on cold blocks; hits should drive what lands on NVMe."
- "LMCache on the vLLM stack is helping concurrency, but we need better observability on cache hit rate per tenant."
- "If the working set keeps growing, consider the remote persistent tier so KV survives pod restarts and we get cross-session reuse."
Related Reading
References
- KV Cache Offloading | NVIDIA Dynamo
Official Dynamo docs for CPU/disk KV cache offloading backends for vLLM.
- KV Cache Offloading (vLLM Production Stack + LMCache)
How to enable KV cache offloading in vLLM using LMCache; CPU/disk tiers.
- A Roadmap for KV Cache Offloading at Scale
Describes durable remote storage, orchestration, and multi-session/multi-node reuse.
- NVMe KV Cache Offloading for LLM Inference: Serve 10x ...
Notes NVMe is slower than HBM; gains come from skipping prefill; cites TTFT cuts on 128K.
- Native KV Cache Offloading to Any Filesystem with llm-d
Shows scaling behavior; storage-backed caching sustains throughput at large working sets.