Motivation
vLLM's automatic prefix caching reuses KV-cache blocks only when the computed block-hash chain matches at full-block granularity. The hash includes the parent block hash, the current block tokens, and optional extra keys such as LoRA IDs, multimodal input hashes, and cache salts. As a result, small prompt-formatting differences, per-request metadata, different chat templates, LoRA/multimodal metadata, or cache-salt differences can prevent reuse even when prompts look similar to a human.
Today, users can inspect prefix-cache behavior through runtime logs, Prometheus metrics, and benchmark scripts, but there is no user-facing, no-GPU way to analyze a request dataset before deployment and answer whether its prompt structure is cache-friendly. This makes it difficult to reason about RAG, agent, tool-calling, and multi-turn workloads before spending GPU time on a serving run.
Related user pain: #29944, #12077, #24394, and the forum thread "How log kvcache usage and prefix hit rate in offline infer?".
Proposal
Add an offline prefix-cache analyzer CLI, tentatively:
vllm analyze-prefix-cache \
--model meta-llama/Meta-Llama-3-8B-Instruct \
--input requests.jsonl \
--format openai-chat \
--block-size 16 \
--output-format text
Given a JSONL of requests and a model/tokenizer, the analyzer would:
- Parse OpenAI batch-style requests and/or plain prompt JSONL.
- Apply the selected chat template and tokenize each request.
- Compute the same full-block hash-chain structure used by vLLM prefix caching, reusing existing request/block hashing utilities rather than reimplementing hashing logic.
- Group requests by shared hash-chain prefixes.
- Report offline cacheability estimates, including:
- total prompt tokens
- total full-block tokens
- estimated reusable full-block tokens
- estimated cacheability ratio
- top shared prefix groups
- request groups that diverge after a common prefix
- Support both human-readable text output and machine-readable JSON output.
This is static analysis over tokenized requests and existing hashing utilities. It should not instantiate the engine, execute model weights, or require GPU access.
Design question: internal API usage
The hashing logic this proposal depends on (hash_block_tokens, generate_block_hash_extra_keys, get_request_block_hasher) currently lives in vllm/v1/core/kv_cache_utils.py — internal to the engine core. A CLI/frontend module importing directly from v1/core crosses a layering boundary that may not be acceptable as-is. Before implementation, we'd like maintainer input on whether this warrants a small, stable public helper for offline hash-chain construction, versus importing the internal utilities directly for a first version.
Scope for v1
- CLI command for offline workload analysis.
- Text output by default.
- JSON output for automation and CI/capacity-planning workflows.
- Support for plain prompt JSONL and OpenAI-compatible chat/batch request JSONL.
- Block-size parameter support, with optional comparison across multiple block sizes.
- Mechanical divergence reporting: show where hash chains stop matching and which request groups share common full-block prefixes.
- Documentation with RAG, agent, tool-calling, and multi-turn examples.
Explicit non-goals for v1
- Exact runtime prefix-cache hit-rate prediction.
- Modeling scheduler behavior, eviction, memory pressure, request arrival order, preemption, KV offload, or disaggregated serving.
- Natural-language cause classification such as "this miss was caused by timestamps" or "this miss was caused by per-user IDs."
- Full multimodal/LoRA/cache-salt inference unless the relevant metadata is present in the input format and can be passed through the same hashing path.
- Engine behavior changes.
The analyzer should present results as an offline upper-bound or cacheability estimate, not as a guarantee of production hit rate.
Alternatives considered
Existing runtime metrics — Runtime metrics and logs can show prefix-cache behavior after a server or offline inference run, but they do not provide a pre-flight analysis tool for a request corpus.
benchmarks/benchmark_prefix_caching.py — Benchmarks prefix-caching performance by running an actual model with fixed prompts or ShareGPT-style prompts. This proposal is different: it does not run inference, does not require GPU, and analyzes a user's request dataset structurally before deployment.
Hash microbenchmarks — Existing hash benchmarks are useful for comparing hashing throughput and algorithm choices, but they do not estimate cacheability of a real prompt workload.
Open questions
- Should this be a top-level command such as
vllm analyze-prefix-cache, or should it live under an existing CLI family such as vllm bench prefix-cache-analyze?
- What input formats should v1 support beyond plain prompts and OpenAI-compatible request JSONL?
- Should JSON output be considered stable in v1, or marked experimental?
- How much LoRA, multimodal, and cache-salt metadata should v1 support?
- Should block-size comparison be built into v1, or added later?
Happy to implement this if the design direction is acceptable.
Motivation
vLLM's automatic prefix caching reuses KV-cache blocks only when the computed block-hash chain matches at full-block granularity. The hash includes the parent block hash, the current block tokens, and optional extra keys such as LoRA IDs, multimodal input hashes, and cache salts. As a result, small prompt-formatting differences, per-request metadata, different chat templates, LoRA/multimodal metadata, or cache-salt differences can prevent reuse even when prompts look similar to a human.
Today, users can inspect prefix-cache behavior through runtime logs, Prometheus metrics, and benchmark scripts, but there is no user-facing, no-GPU way to analyze a request dataset before deployment and answer whether its prompt structure is cache-friendly. This makes it difficult to reason about RAG, agent, tool-calling, and multi-turn workloads before spending GPU time on a serving run.
Related user pain: #29944, #12077, #24394, and the forum thread "How log kvcache usage and prefix hit rate in offline infer?".
Proposal
Add an offline prefix-cache analyzer CLI, tentatively:
Given a JSONL of requests and a model/tokenizer, the analyzer would:
This is static analysis over tokenized requests and existing hashing utilities. It should not instantiate the engine, execute model weights, or require GPU access.
Design question: internal API usage
The hashing logic this proposal depends on (
hash_block_tokens,generate_block_hash_extra_keys,get_request_block_hasher) currently lives invllm/v1/core/kv_cache_utils.py— internal to the engine core. A CLI/frontend module importing directly fromv1/corecrosses a layering boundary that may not be acceptable as-is. Before implementation, we'd like maintainer input on whether this warrants a small, stable public helper for offline hash-chain construction, versus importing the internal utilities directly for a first version.Scope for v1
Explicit non-goals for v1
The analyzer should present results as an offline upper-bound or cacheability estimate, not as a guarantee of production hit rate.
Alternatives considered
Existing runtime metrics — Runtime metrics and logs can show prefix-cache behavior after a server or offline inference run, but they do not provide a pre-flight analysis tool for a request corpus.
benchmarks/benchmark_prefix_caching.py— Benchmarks prefix-caching performance by running an actual model with fixed prompts or ShareGPT-style prompts. This proposal is different: it does not run inference, does not require GPU, and analyzes a user's request dataset structurally before deployment.Hash microbenchmarks — Existing hash benchmarks are useful for comparing hashing throughput and algorithm choices, but they do not estimate cacheability of a real prompt workload.
Open questions
vllm analyze-prefix-cache, or should it live under an existing CLI family such asvllm bench prefix-cache-analyze?Happy to implement this if the design direction is acceptable.