- you serve RAG workloads where the same documents are retrieved in varying order across requests
- prompt reuse is non-prefix — shared blocks sit after a per-request preamble, system prompt, or other documents
- prefix caching alone leaves you re-prefilling content you have already seen
Prerequisites
CacheBlend requires the following minimum versions, plus cert-manager:| Component | Minimum version |
|---|---|
| Tensormesh Operator helm chart | 0.5.1-rc1 |
LMCache Operator (lmcache/lmcache-operator) | v0.5.0 |
LMCache vLLM (lmcache/vllm-openai) | v0.5.0 |
cacheblend-plugin (private image) | latest-nightly |
| cert-manager | any recent release |
Configuration
CacheBlend needs two namespaces:- the operator namespace (the Helm release namespace)
- a workload namespace — PSS-privileged; holds the
CacheBlendEngine, its connection ConfigMap, the opt-in vLLM pods, and the cacheblend-plugin private-image pull secret
my-values.yaml
Opting a vLLM pod in
CacheBlend attaches to vLLM pods you deploy — the operator does not create them. In the workload namespace, add two things to your vLLM pod template, and launch vLLM args-only (command: override makes the webhook skip injection):
hostIPC, the CUSTOM attention backend, and the
--kv-transfer-config (CBKVConnector) pointing at the node-local engine; blend tunables
(cb.check_layer, cb.recomp_ratio) come from the engine config.
Helm values reference
| Value | Type | Default | Description |
|---|---|---|---|
cacheBlend.enabled | bool | false | Create a CacheBlendEngine CR. Requires webhook.enabled: true + cert-manager. |
cacheBlend.name | string | "" | Engine CR name. Empty = <fullname>-cacheblend. |
cacheBlend.namespace | string | "" | Namespace for the engine + its connection ConfigMap. Use a non-release, PSS-privileged workload namespace. Empty = release namespace. |
cacheBlend.spec.l1.sizeGB | int | 60 | L1 (host-DRAM) chunk cache size, in GiB. |
cacheBlend.spec.image | object | lmcache/vllm-openai | Blend-engine image (the lmcache server). |
cacheBlend.spec.injection.payloadImage | object | — | PRIVATE cacheblend-plugin image injected as the init container. Must match the engine’s lmcache build. |
cacheBlend.spec.injection.imagePullSecrets | list | [] | Pull secret names appended to opt-in pods for the private payload image. The Secret(s) must already exist in the vLLM pod’s namespace. |
webhook.enabled | bool | true | Enable the CacheBlend mutating webhook. Requires cert-manager. |
Verification
Engine reconciled
<engine>-connection ConfigMap is the reconcile proof — and the gate the webhook reads. If it
is missing, injection silently fail-opens (the pod runs without CacheBlend).
Webhook wired
caBundle means cert-manager issued the serving cert and the webhook can be called.
Injection happened
After creating an opt-in vLLM pod in the workload namespace:Non-prefix blend actually engaged (optional)
Send two requests that share a block after different-length preambles, then check the engine logs. Ashifted retrieve means a chunk was reused at a different position than it was cached —
i.e. a non-prefix blend:
Common mistakes
- Running the opt-in vLLM pod in the operator (release) namespace — the webhook excludes it, so injection never happens
- Setting a
command:on the vLLM container — the webhook skips injection (appended args would never reachvllm serve) - Workload namespace not PSS-privileged — Pod Security rejects the injected
hostIPC - The
cacheblend-plugin-pullsecret missing from the workload namespace — the injected init containerImagePullBackOffs (the secret must live where the pod runs, not in the operator namespace) - Mismatched
cacheblend-pluginandvllm-openaiimages — vLLM crashes at startup with anImportError; pin a matched pair webhook.enabled: falseor no cert-manager — the engine deploys but nothing injects the plugin

