Systems & Optimization2023intermediate11 min read
Efficient Memory Management for Large Language Model Serving with PagedAttention
إدارة الذاكرة بكفاءة لخدمة النماذج اللغوية الكبيرة باستخدام PagedAttention
Kwon, W. · Li, Z. · Zhuang, S. · Sheng, Y. · Zheng, L. · Yu, C. H. · Gonzalez, J. E. · Zhang, H. · Stoica, I. — SOSP
The problem
Serving large language models requires holding a key-value cache () in memory for every active request. This cache grows token by token during and its final size is unknown in advance. Existing systems reserve a contiguous memory block sized for the maximum possible , wasting 60–80% of precious GPU memory to , , and redundant duplication. This waste directly limits the — and therefore the — of the serving system.
The contribution
PagedAttention stores the KV cache in fixed-size blocks that can live anywhere in GPU memory, mapped through a — exactly like and in operating systems. This eliminates fragmentation and enables on-demand allocation. On top of it, the authors built vLLM, a serving system that achieves near-zero memory waste and supports sharing of KV cache blocks across sequences for parallel sampling and . vLLM improved throughput by 2–4× over FasterTransformer and Orca at the same .
The impact
PagedAttention became the industry standard for KV cache management in LLM serving. It is now the default memory manager in vLLM and has been adopted by TensorRT-LLM, Hugging Face TGI, and virtually every major framework. The paper reframed LLM serving as a memory-systems problem, importing decades of operating-system wisdom into machine learning infrastructure, and enabling the economic viability of large-scale LLM deployment.
Imagine a hotel that assigns every guest a presidential suite — whether they stay one night or a month — and won't let anyone else use the empty rooms. Most of the hotel sits dark while travelers camp in the lobby.
Now imagine the hotel switches to a system borrowed from apartment buildings: rooms are rented one at a time, they don't have to be next to each other, and a front-desk ledger maps each guest to their scattered rooms. The same hotel suddenly houses four times as many guests.
This paper brought exactly that idea — virtual memory and paging from operating systems — to the GPU memory that stores the KV cache during LLM serving.
The bottleneck: KV cache memory waste
When a large language model generates text, it produces one token at a time. At each step the model computes new key and value vectors for the mechanism. To avoid recomputing these vectors from scratch at every step, the system stores them in a key-value cache (KV cache). For a 13-billion-parameter model, a single request's KV cache can consume up to 1.7 GB of GPU memory.
The critical challenge is that the KV cache grows dynamically — one block of vectors per generated token — and its final size depends on the output length, which is unknown before generation finishes. Existing systems handle this by pre-allocating a contiguous memory region sized for the maximum possible sequence length. This causes three forms of waste.
First, internal fragmentation: the reserved region is almost always larger than the actual sequence, so the tail of each allocation is empty. Second, external fragmentation: as requests arrive and depart, the free memory becomes scattered into chunks too small for new allocations. Third, redundant duplication: techniques like parallel sampling and beam search generate multiple outputs from the same prompt, yet each copy stores its own full KV cache — even for the shared prefix.
Measurements on production systems show that these three wastes together consume 60–80% of KV cache memory. This directly limits the batch size, because fewer concurrent requests fit in GPU memory, which in turn reduces throughput.
The insight: virtual memory for KV cache
Operating systems solved the exact same problem decades ago. In the 1960s, programs needed contiguous physical memory, which led to the same fragmentation nightmares. The solution was virtual memory with paging: give each program a contiguous logical address space, but map it to scattered physical pages through a page table. Programs see tidy consecutive addresses; the OS handles the messy physical layout.
PagedAttention imports this idea wholesale. Each request's KV cache is divided into fixed-size logical blocks (analogous to virtual pages). These logical blocks are mapped to physical blocks in GPU memory through a block table (analogous to a page table). The physical blocks do not need to be contiguous. The block manager allocates physical blocks on demand — one at a time — as new tokens are generated.
Think of it as giving each request a numbered notebook. The request writes on page 1, then page 2, then page 3. But page 1 might live on shelf A, page 2 on shelf G, and page 3 on shelf C. The block table is the index card that says "page 1 → shelf A, page 2 → shelf G, page 3 → shelf C." The request never notices the scattering.
The PagedAttention algorithm
Standard attention computes a weighted combination of all value vectors, where the weights come from the dot product of the with each key. In a standard implementation, the keys and values for a single sequence are stored in contiguous tensors.
PagedAttention modifies the attention kernel so that keys and values are fetched block-by-block from non-contiguous physical locations. For each query vector, the kernel iterates through the block table, gathers the relevant key and value blocks, computes the partial attention within each block, and accumulates the result. The mathematical output is identical to standard attention — only the memory layout changes.
Concretely, let the block size be tokens. The KV cache for a sequence of length is divided into blocks. For each attention head, the keys in block form a matrix and the values form , where is the head dimension. The attention for a single query is:
vLLM: the serving system built on PagedAttention
vLLM is a complete LLM serving system that uses PagedAttention as its memory foundation. The architecture has three key components: a centralized scheduler that decides which requests to process at each step, a KV cache manager (block manager) that handles allocation and deallocation of physical blocks, and a set of GPU workers that execute the model with the PagedAttention kernel.
The scheduler implements (also called iteration-level scheduling): instead of waiting for an entire batch to finish before accepting new requests, it re-evaluates the active set at every single token-generation step. A request that finishes early immediately releases its blocks, and a new request can start in the same step. This eliminates the GPU idle time that plagued static batching.
The block manager tracks a free list of physical blocks, maintains reference counts for shared blocks, and performs copy-on-write when a shared block needs to be modified. It also handles : when GPU memory runs low, the scheduler can pause a lower-priority request by either swapping its blocks to CPU memory or simply freeing them for recomputation later. This ensures the system never deadlocks due to memory pressure.
Memory sharing: copy-on-write for parallel decoding
Many decoding strategies generate multiple output sequences from the same prompt. In parallel sampling, the model generates independent completions from the same input. In beam search, candidate sequences expand in parallel at each step. Both scenarios share a prefix: all sequences begin with the same prompt tokens and therefore share identical KV cache entries for those positions.
Without sharing, each sequence would duplicate the entire prompt's KV cache. With PagedAttention, all sequences point to the same physical blocks for the shared prefix. Only when a sequence needs to write a new token into a previously shared block does copy-on-write trigger: the system copies the block to a new physical location and updates that sequence's block table. This is identical to how Unix implements the fork() system call.
Measurements show 6–10% memory savings for parallel sampling and 37–55% savings for beam search. On the ShareGPT dataset with longer shared prefixes, savings reach up to 66% for beam search.
Results: 2–4× throughput improvement
The authors evaluated vLLM against two state-of-the-art baselines: NVIDIA's FasterTransformer and Orca (the system that introduced continuous batching). They tested on OPT models (13B and 175B parameters) with real conversation datasets (ShareGPT and Alpaca).
Under basic sampling, vLLM achieved 2–4× higher throughput than FasterTransformer and 1.7–2.7× higher than Orca, with the same or lower latency. The improvement grew with longer sequences and larger models, because memory pressure is more severe in those settings. Under beam search, the gains were even larger due to copy-on-write sharing.
Memory waste measurements confirmed the mechanism: existing systems wasted 60.4–80.3% of KV cache memory, while vLLM wasted less than 4%. The only remaining waste is internal fragmentation in the last block of each sequence, bounded by the block size .
Under the hood: block table lookup
Simplified to show the idea — not the real implementation.
def paged_attention(query, key_cache, value_cache, block_table, block_size):
"""Compute attention over non-contiguous KV blocks."""
d = query.shape[-1]
num_blocks = len(block_table)
# Accumulate weighted values across blocks
output = zeros_like(query)
total_exp = 0.0
global_max = -inf
for j in range(num_blocks):
# Look up physical block from block table
phys_block = block_table[j]
K_j = key_cache[phys_block] # shape: [B, d]
V_j = value_cache[phys_block] # shape: [B, d]
# Compute attention scores for this block
scores = query @ K_j.T / sqrt(d) # shape: [B]
block_max = max(scores)
# Numerically stable accumulation
correction = exp(global_max - max(global_max, block_max))
exp_scores = exp(scores - max(global_max, block_max))
output = output * correction + exp_scores @ V_j
total_exp = total_exp * correction + sum(exp_scores)
global_max = max(global_max, block_max)
return output / total_expTimeline: from OS paging to LLM serving standard
1962
Virtual memory invented
Atlas computer at Manchester introduced virtual memory with paging, solving physical memory fragmentation for general-purpose programs.
2017
Transformer architecture published
"Attention Is All You Need" introduced the transformer, whose multi-head attention requires storing key-value pairs for all past tokens.
2022
Orca introduces continuous batching
Orca proposed iteration-level scheduling, allowing new requests to join a batch at each decoding step. However, it still used contiguous KV cache allocation.
2023
PagedAttention and vLLM (this paper)
Kwon et al. applied OS-style paging to KV cache management, achieving near-zero waste and 2–4× throughput improvement. Published at SOSP 2023.
2024
PagedAttention becomes the industry norm
TensorRT-LLM, Hugging Face TGI, SGLang, and MLC-LLM all adopted paged KV cache management. FlashAttention-2 was layered underneath for the compute kernel.
2025
vAttention and beyond
vAttention proposed keeping KV cache contiguous in virtual memory while using OS demand paging for physical allocation — keeping standard attention kernels unmodified. The paging paradigm continues to evolve.
PagedAttention's deepest contribution is not the 2–4× speedup — it is the reframing. Before this paper, LLM serving was treated as a pure ML systems problem. After it, the field recognized that memory management is the binding constraint, and that decades of OS research offer a ready toolkit. This shift in perspective opened the door to a generation of serving optimizations: prefix caching, radix attention, disaggregated prefill/decode, and — all of which build on the paged memory abstraction that this paper introduced.
CitationKwon, Li, Zhuang, Sheng, Zheng, Yu, Gonzalez, Zhang, Stoica. Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP, 2023.
Terms in this paper
- KV Cacheذاكرة المفاتيح والقيم
- Pagingنظام الصفحات
- Virtual Memoryالذاكرة الافتراضية
- Block Tableجدول الكتل
- Copy-on-Writeالنسخ عند الكتابة
- Continuous Batchingالدُّفعات المستمرة
- Preemptionالاستباق
- Beam Searchبحث الحزمة
- Throughputمعدل التدفق والإنتاجية
- Autoregressive Generationالتوليد الارتجاعي
- GPUوحدة معالجة الرسوميات
- Attentionآلية الانتباه
- Transformerالمحوِّل
- Inferenceالاستدلال
- Latencyزمن الاستجابة (التأخير البيني)