How to Reduce LLM Inference Cost on Kubernetes

Training got the headlines; inference is where the money actually goes. A model is trained a handful of times and served millions. If your AI GPU bill is climbing, it's almost certainly your serving fleet — and most of that cost is recoverable without touching model quality. Here are the levers, in the order that usually pays off fastest.

💡 Want the number before the fixes? The free GPU Idle-Cost Calculator shows what your current utilization is costing per year. Two minutes, no signup.

The one metric that governs cost: throughput per GPU

Inference cost reduces to a single ratio: tokens served per GPU-hour ÷ your $/GPU-hour. You lower cost either by raising the numerator (serve more tokens on the same card) or lowering the denominator (cheaper cards, spot). Everything below is one of those two moves. And because a GPU bills at 100% whether it's saturated or idle, the fastest wins come from raising throughput on hardware you're already paying for.

1. Continuous batching — the single biggest throughput win

Naive serving processes one request (or one static batch) at a time; the GPU stalls waiting for the slowest sequence to finish. A modern serving engine — vLLM, TGI, TensorRT-LLM — uses continuous (in-flight) batching: it admits new requests into the running batch as slots free up, so the GPU stays saturated across many concurrent users. For real, concurrent traffic this is typically the largest single improvement in cost-per-token you can make, and it's a serving-layer change — the model is untouched. If you're still serving LLMs from a hand-rolled Flask/FastAPI loop, this is where to start.

2. KV-cache: the hidden memory (and cost) driver

Every token of context is held in the KV-cache, and that memory — not the weights — usually dictates how many concurrent requests fit on a GPU. Two consequences for cost:

3. Quantization — fit more model on less GPU (with eyes open)

Serving weights at lower precision (FP8, INT8, INT4 via AWQ/GPTQ and similar) shrinks the memory footprint and can raise throughput, which often lets a model drop to a smaller GPU or fewer of them — a direct cost cut. The honest tradeoff: quantization can degrade quality, and how much depends on the model and the method. Treat it as a change to validate, not a free win: run your own eval set before and after and decide with numbers. Done right it's one of the highest-leverage cost moves; done blindly it's a quality regression you'll discover in production.

4. Right-size the replica to the model

A frequent, silent waste: serving a model that fits comfortably on one GPU across a multi-GPU replica "for headroom," or reserving a whole 80GB card for a small model. Tensor/pipeline parallelism has real overhead — split a model across more GPUs than it needs and you pay in both idle capacity and communication cost. Right-sizing means: use the fewest GPUs the model and your latency target actually require, and pack small models onto shared or partitioned GPUs (see MIG and time-slicing) rather than giving each its own card.

5. Autoscale on the right signal for bursty traffic

Inference traffic is spiky, and this is where money leaks. If you provision replicas for peak, GPUs sit idle between bursts while billing at 100%. The fix is autoscaling — but CPU/memory HPA is the wrong signal for LLM serving. Scale on a request-aware metric instead: queue depth, requests/pending per replica, or a custom throughput metric exported from your serving engine, driven through KEDA or a custom-metrics HPA. Two caveats that make it safe:

6. Cheaper GPU-hours: spot and the right accelerator

The denominator lever. Interruption-tolerant inference — async/batch scoring, offline generation, anything idempotent and retryable — runs well on spot/preemptible GPU nodes at a large discount, provided you handle preemption gracefully (fast drain, ret/requeue, a warm on-demand floor for latency-critical traffic). Separately, match the accelerator to the workload: the newest, largest GPU isn't always the cheapest per token for a small model, and a smaller card at high utilization can beat a big one at 30%.

Putting it together

LeverWhat it movesWatch out for
Continuous batchingThroughput per GPU ↑↑Requires a real serving engine
KV-cache mgmt / prefix cachingConcurrency per GPU ↑Long contexts cap batch size
QuantizationModel fits smaller/fewer GPUsValidate quality on your evals
Right-sizing replicasRemoves idle/over-parallelismRespect latency target
Request-aware autoscalingKills between-burst idleCold starts; keep a warm floor
Spot + right accelerator$/GPU-hour ↓Only interruption-tolerant work

The pattern across all six: utilization is the multiplier. A serving fleet averaging 30% utilization is paying roughly 3× per useful token versus one kept busy. Fix batching and autoscaling first — they raise utilization without any model risk — then take the model-level wins (quantization, right-sizing) with your evals in hand.

Start with the number: the free GPU Idle-Cost Calculator turns your fleet size and utilization into an annual waste figure in two minutes.

And when you want a human to find the waste on your actual cluster — the idle replicas, the mis-sized models, the autoscaling that never fires — book a GPU Cost & Reliability Audit →
Get the next field note. Practical, occasional notes on GPU/K8s cost and AI-infra — the traps and the numbers. No spam.