Skip to content

49 · RadixAttention, Eviction & Cache Churn ​

Source: fanout.sh / inference-eng / 10-07 · ~6 min

NOTE

Real prompts share in layers, so the shared parts form a tree. RadixAttention (SGLang) caches that tree in a radix tree whose edges hold token runs and their K, V, matching down to a single token; finished requests, outputs included, stay for the next turn. The cache is finite: SGLang evicts unpinned, least recently used leaves first, so shared trunks survive longest, and serving the longest cached prefix first walks the tree depth-first for the best hit rate (up to 6.4× throughput reported). When the working set outgrows the cache, LRU can churn: 5 prefixes cycling through room for 4 gives 0 hits in 10.

1. Sharing comes in layers ​

Prefix treeOne radix tree holding all three patterns; the chat's turns compress into a single edge until something branches off it.

  • A system prompt, then a few examples, then different questions.
  • A chat that grows one turn at a time.
  • An agent that forks into several attempts from the same point.
  • The shared parts form a tree, and the cache holding it is finite: something has to decide what to keep.

2. RadixAttention: caching the tree ​

Radix tree steps◆ Built by a ~30-line radix tree on word tokens; the counts are its real output.

  • From the SGLang project. Cached K and V live in a radix tree: each edge is a run of tokens and holds those tokens' KV cache.
  • Request 1 (system prompt + Q1) becomes a single path from the root.
  • Request 2 shares the system prompt but asks Q2. The lookup walks down token by token until the tokens differ; there the edge splits into a shared part and two branches. The shared part is reused; only Q2 is computed.
  • When a request finishes, its whole path, including the generated answer, stays in the tree, so the next turn finds its entire history cached.

3. vs vLLM's prefix caching ​

GranularityTokens reused as a function of shared prefix length.

vLLMSGLang RadixAttention
Structurechained hashes of blocksradix tree
Match granularitysteps of 16 tokensdown to a single token
Sharingreference countsreference counts
Evictionleast recently used firstleast recently used first
  • Same goal: reuse any shared prefix, automatically.

4. Eviction ​

Eviction◆ The order numbers come from simulating the rules below on this tree.

  • In SGLang, the cache and the running requests share one memory pool. When a bigger batch needs room, the cache shrinks.
  • Some nodes can never be evicted: every running request pins its path with a reference count. Only nodes with count 0 are candidates.
  • Only leaves go first, and among them the least recently used leaf is evicted.
  • When all of a node's children are gone, it becomes a leaf and can be evicted later. So shared trunks survive the longest, which is exactly what you want.

5. Order matters ​

Scheduling order◆ Simulated LRU cache that holds one prefix, same 9 requests in two orders.

  • Waiting requests often fall into groups sharing different prefixes. Served in arrival order, the cache keeps switching between groups.
  • SGLang can serve the longest cached prefix first. That walks the tree depth-first, finishing one branch before the next.
  • For a fixed batch, the paper proves this order gives the best possible hit rate. ◆ The theorem assumes the cache can hold at least the longest request.
  • The risk is starvation: a request with no shared prefix can keep getting pushed back.
  • SGLang (NeurIPS '24) reported up to 6.4× the throughput of other systems of the time, on workloads full of shared structure.

6. Cache churn ​

ChurnLeft: the lesson's example, re-simulated. Right ◆: the same cycle repeated 200 times at different cache sizes.

  • Cache with room for 4 prefixes; 5 prefixes arrive in a repeating cycle: A, B, C, D, E.
  • E doesn't fit, so LRU evicts A. Then A returns and evicts B; B returns and evicts C… 0 hits in 10 requests, even though every prefix repeats.
  • Group the same traffic by prefix (A, A, B, B, …) and half of them hit (5/10).

WARNING

◆ Under cyclic access, LRU always evicts exactly the prefix that's needed next. So the hit rate stays at 0% until the cache holds the whole working set, then jumps to 100%. One prefix too few costs everything.

FixesSymptoms and fixes, as listed in the lesson.

7. Recap ​

Lesson 49 recap card