What is RadixAttention?
RadixAttention combines two key innovations:- Radix Tree Data Structure: Organizes KV cache as a tree where common prefixes are shared
- Attention Mechanism: Efficiently computes attention over the shared tree structure
The Radix Tree
The RadixCache inpython/sglang/srt/mem_cache/radix_cache.py implements a prefix tree (trie) data structure:
python/sglang/srt/mem_cache/radix_cache.py:117-146
Example Tree Structure
Consider three requests:- Request 1: “What is the capital of France?”
- Request 2: “What is the capital of Germany?”
- Request 3: “What is the weather today?”
The shared prefix “What is the” is stored only once in memory and reused by all three requests.
Key Operations
Prefix Matching
When a new request arrives, RadixCache finds the longest cached prefix:python/sglang/srt/mem_cache/radix_cache.py:371-441
Prefix matching happens at page granularity when
page_size > 1. If page_size=16, prefixes are aligned to 16-token boundaries.Prefix Insertion
After a request completes, its tokens and KV cache are inserted into the tree:python/sglang/srt/mem_cache/radix_cache.py:443-457
Node Splitting
When a match ends in the middle of a node, the node is split:python/sglang/srt/mem_cache/radix_cache.py:687-706
Memory Management
Reference Counting
Each node maintains a reference count:python/sglang/srt/mem_cache/radix_cache.py:607-620
Eviction Policies
When memory is full, nodes are evicted based on configurable policies:- LRU (Least Recently Used): Evicts oldest accessed nodes
- LFU (Least Frequently Used): Evicts least accessed nodes
- FIFO (First In First Out): Evicts oldest inserted nodes
- MRU (Most Recently Used): Evicts most recent nodes
- FILO (First In Last Out): Stack-based eviction
- Priority: Evicts based on request priority
python/sglang/srt/mem_cache/radix_cache.py:578-605
Attention Computation
The RadixAttention layer (python/sglang/srt/layers/radix_attention.py) computes attention over the tree structure:
python/sglang/srt/layers/radix_attention.py:99-135
The attention backend (FlashInfer, FlashAttention, etc.) handles the actual computation, accessing cached KV states through the indices provided by RadixCache.
Performance Benefits
Memory Savings
With shared prefixes, memory usage scales with unique content rather than total tokens:- Without prefix caching: 3 requests × 1000 tokens = 3000 tokens in memory
- With prefix caching: 800 shared + 3 × 200 unique = 1400 tokens (53% savings)
Computation Savings
Cached KV states don’t need to be recomputed:- Prefill time: Only compute attention for new (uncached) tokens
- TTFT (Time to First Token): Dramatically reduced for requests with cached prefixes
Integration with Scheduler
The scheduler automatically uses RadixCache during request processing:python/sglang/srt/managers/schedule_policy.py:182-240
Page Alignment
For efficient memory management, prefixes can be aligned to page boundaries:python/sglang/srt/mem_cache/radix_cache.py:110-114
Partial pages at the end of sequences are not cached. This ensures page-granular sharing and efficient memory allocation.
Configuration
Configure RadixAttention behavior:Limitations
- Exact Match Required: Token sequences must match exactly (including special tokens)
- Memory Overhead: Tree structure adds small overhead vs flat arrays
- Eviction Cost: Finding eviction candidates requires heap operations
- Locking Granularity: Entire paths are locked, not individual nodes
Related Topics
- Prefix Caching - Detailed caching strategies
- System Architecture - Overall system design
- Continuous Batching - Dynamic batch management
