Skip to main content
Source

This page is generated from skills/eks-genai/references/kv-cache-and-cost.md. Edit the source, not this page.

KV-Cache Tiering & Cost Optimization

Opinionated guidance for KV-cache tiering with LMCache and the priority-ordered cost-optimization levers for GenAI workloads on EKS. Always directional ranges with caveats — never point estimates.

KV-Cache Tiering with LMCache

LMCache adds a multi-tier cache for KV tensors in front of vLLM — reusing computed attention states across requests that share prompt prefixes. This eliminates redundant prefill computation for system prompts, RAG contexts, and tool-call preambles.

Cache Hierarchy

L0 GPU VRAM — vLLM's native PagedAttention cache (always present)
L1 CPU RAM — LMCache local CPU tensor store (same pod, DRAM)
L2 Remote store — Amazon ElastiCache Serverless (Valkey) via TLS
TierLatencyCapacityWhen it helps
L0 GPU VRAM~0 (in-place)Limited by --gpu-memory-utilizationEvery request (vLLM built-in)
L1 CPU RAM~1-5 msConfigurable via LMCACHE_MAX_LOCAL_CPU_SIZE (GB)Same-pod repeated prefixes; single-replica workloads
L2 Remote Valkey~5-15 ms (same-AZ TLS)Effectively unbounded (ElastiCache Serverless scales)Multi-pod prefix sharing; long/shared contexts across replicas

When L2 adds value: Multi-pod deployments where different replicas serve requests with overlapping prefixes (RAG contexts, system prompts, agentic tool preambles). For short, unique prompts on a single pod, L1 CPU is sufficient — the network fetch to L2 can be slower than recompute.

Measured Performance

Workshop-validated on g6e.2xlarge (L40S), Ministral-3-8B-Instruct-2512, 90% prompt overlap:

MetricCold (no cache)Warm (L1/L2 hit)Speedup
TTFT0.43 s0.12 s~3.6×

The speedup scales with prompt overlap percentage and prompt length — longer shared prefixes yield larger savings. Short unique prompts see negligible benefit.

LMCache Configuration

# Environment variables on vLLM pod
LMCACHE_LOCAL_CPU=True # enable L1 CPU tier
LMCACHE_MAX_LOCAL_CPU_SIZE=8 # GB of CPU RAM for L1
LMCACHE_REMOTE_URL=rediss://my-valkey.cache.amazonaws.com:6379 # TLS (double-s)
LMCACHE_CHUNK_SIZE=256 # tokens per cache chunk
LMCACHE_REMOTE_SERDE=naive # serialization format

# Required vLLM settings when LMCache is active
VLLM_ATTENTION_BACKEND=FLASHINFER # required
PYTHONHASHSEED=0 # cross-pod cache-key stability

vLLM launch args when LMCache is wired:

--enforce-eager # required with FLASHINFER + LMCache
--kv-transfer-config '{"kv_connector":"LMCacheConnectorV1","kv_role":"kv_both"}'

ElastiCache Serverless (Valkey) for L2

Deploy Amazon ElastiCache Serverless with Valkey engine as the L2 backing store:

  • TLS required — the rediss:// (double-s) scheme enables in-transit encryption
  • Same-AZ as vLLM pods — cross-AZ adds 1-3 ms round-trip that erodes the cache benefit
  • Security group — allow inbound TCP 6379 from the vLLM pod security group only
  • IAM auth — use ElastiCache IAM authentication with EKS Pod Identity for zero-secret configuration

Prefix Caching Strategy

LMCache is most effective when requests share long prefixes. Design your prompts to maximize prefix overlap:

PatternPrefix overlapLMCache benefit
System prompt + user queryHigh (system prompt cached)✅ Strong — system prompt computed once
RAG context + questionHigh (same retrieved docs across users)✅ Strong — context block cached
Agentic tool preamble + tool callHigh (tool definitions cached)✅ Strong — tool schema computed once
Unique user conversations (no shared prefix)Low⚠️ Minimal — recompute is faster than cache fetch

Decision rule: Enable LMCache when ≥ 50% of request tokens are shared prefixes across requests. Skip for workloads with unique, short prompts.

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│ EKS Cluster │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ vLLM Pod 1 │ │ vLLM Pod 2 │ │ vLLM Pod 3 │ │
│ │ L0: GPU KV │ │ L0: GPU KV │ │ L0: GPU KV │ │
│ │ L1: CPU RAM │ │ L1: CPU RAM │ │ L1: CPU RAM │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ rediss:// (TLS) │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Amazon ElastiCache Serverless (Valkey) — L2 │ │
│ │ Same-AZ as vLLM pods │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Cost-Optimization Levers (Priority Order)

Savings levers ordered by impact. Apply top-down — each lever is independent; stack them for compounding savings.

PriorityLeverDirectional savingsWhen to applyCaveat
1Capacity Blocks for MLCapacity assurance (not a fixed discount)Planned multi-day training runs; guaranteed p5/p5e/trn2 capacityReservation-fee pricing set by supply/demand — AWS publishes no fixed discount vs on-demand; primary value is guaranteed access, not savings. Requires advance reservation; not elastic
2Neuron over GPU40-50% price-perfTransformer-family models (Llama, Mistral, Qwen); steady-state production inference on Inf2; training on Trn1/Trn21-2 week compilation ramp; not all architectures supported
3Spot + Checkpoint/Resume60-90% vs on-demandFault-tolerant training with FSx checkpoint loop; dev/experimentationRequires checkpoint logic; interruption risk; NOT for SLA-bound inference
4MIG / Time-Slicing2-7× densityShared dev clusters; small models that don't need a full GPU; multi-tenant experimentationReduced per-slice memory; not for latency-critical production
5Karpenter Consolidation20-40% off-peakInference clusters with variable traffic; off-peak GPU node reclamationSet do-not-disrupt on training pods; aggressive consolidation can increase cold-start
6KV-Cache Tiering + S3 Lazy-Load10-30% compute reductionHigh-overlap prompt workloads (RAG, agentic, system prompts); reduce redundant prefill GPU-secondsRequires LMCache + ElastiCache setup; benefit proportional to prefix overlap

Lever 1 — Capacity Blocks for ML

Reserve GPU/Neuron capacity for defined time windows (1-14+ days) at substantially-below-on-demand pricing. Best for:

  • Planned pre-training runs with known duration
  • Fine-tuning campaigns (e.g., weekly retrain cycle)
  • Benchmark/eval jobs that must not be interrupted

Reference: EC2 Capacity Blocks for ML Pricing.

Lever 2 — Neuron Over GPU

For supported Transformer-family models, Inferentia2 delivers up to ~40% better price-performance than comparable GPU instances, and Trainium delivers up to ~50% cost-to-train savings. The savings are real but require:

  • One-time model compilation (neuron_compile) — budget 1-2 weeks for first model
  • Verification that the specific model architecture is supported
  • Neuron Monitor for observability (different metrics than DCGM)

Reference: AWS EC2 Trn1 Instance Types; AWS EC2 Inf2 Instance Types.

Lever 3 — Spot + Checkpoint

Spot instances for training deliver 60-90% savings vs on-demand — but ONLY when checkpoint/resume is wired:

Without checkpoint: Spot interruption → restart from epoch 0 → COST BURN
With checkpoint: Spot interruption → resume from last checkpoint → max 15-30 min lost

See distributed-training.md for the FSx + S3 DRA checkpoint architecture.

Lever 4 — MIG / Time-Slicing

Multi-Instance GPU (MIG) partitions H100/A100 into isolated GPU slices — each slice gets dedicated memory, compute, and L2 cache. Use for multi-tenant dev clusters where teams share expensive GPU nodes.

Time-slicing shares a single GPU across pods via time-multiplexing — no memory isolation, no compute guarantee. Use only for dev/test where latency doesn't matter.

TechniqueIsolationBest forNot for
MIGMemory + compute + L2Multi-tenant dev; small model experimentation; CI/CD GPU testsProduction inference (per-slice memory limits model size)
Time-slicingNone (cooperative)Dev notebooks; very small models; experimentationAny production workload; latency-sensitive serving

Lever 5 — Karpenter Consolidation

Karpenter automatically right-sizes GPU node count during off-peak. Configure:

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-inference
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 5m # reclaim empty GPU nodes after 5 min idle

Guard: Set karpenter.sh/do-not-disrupt: "true" on training pods — consolidation must not preempt multi-hour training runs.

Lever 6 — KV-Cache Tiering + S3 Lazy-Load

KV-cache tiering (LMCache) reduces redundant GPU compute for overlapping prefixes — each cache hit is prefill GPU-seconds you don't pay for. Compound with S3 lazy-load (Mountpoint S3 CSI or Run:ai Streamer) to eliminate persistent storage costs for model weights.

Combined savings: fewer GPU-seconds per request (cache) + zero EBS/FSx cost for inference-only model storage (S3).

Cost Guardrails

  • Never give point estimates. GenAI costs depend on model size, sequence length, batch profile, traffic pattern, Spot mix, and KV-cache hit rate. Use directional ranges: "expect 30-50% savings with Neuron migration" or "Spot training typically saves 60-90% vs on-demand with proper checkpoint/resume."
  • Always caveat. "Actual savings depend on your specific workload profile — validate with a 2-week pilot before committing capacity changes."
  • Stack levers. Levers 1-6 are independent and composable — a customer using Capacity Blocks (1) + Neuron (2) + KV-cache (6) compounds savings multiplicatively across training + inference.
  • Account for engineering cost. Neuron compilation, checkpoint/resume logic, LMCache integration, and Karpenter tuning all require engineering time. The payback period is typically 4-8 weeks for a dedicated platform team; longer for teams splitting attention.

Anti-Patterns

Anti-patternWhy it's wrongCorrect approach
Spot for SLA-bound inferenceInterruptions break per-request SLAsOn-Demand + Karpenter consolidation for cost savings
GPU for all training (no Neuron evaluation)40-50% savings left on the tableEvaluate Neuron for Transformer-family; GPU for novel architectures
No checkpoint + Spot trainingEvery interruption = full restartFSx + S3 DRA checkpoint every 15-30 min
Full GPU node 24/7 for bursty inferencePaying for idle GPU hoursKarpenter consolidation or KServe scale-to-zero
Pulling model from HF at every pod startEgress cost + rate limits + cold-startPre-cache to S3; use Run:ai Streamer or Mountpoint S3 CSI
Cross-AZ FSx for LustreLatency penalty dwarfs FSx's native performanceSame-AZ FSx + compute nodes

Sources