Skip to content

Ran Your Own LLM on Kubernetes for 30 Days — Here's the Real Cost

The cloud AI cost conversation is two camps shouting past each other: vendor blogs saying "our managed service is cheaper" and Reddit threads saying "self-hosting saves 90%." Neither shows real bills, so neither is useful.

This post shows the real numbers: 30 days, real production traffic, four configurations, every line item. Spoiler — self-hosting was 31% cheaper on the cloud bill and 33% more expensive once you count engineering time. Both facts are true. The details are what matter.


The Setup (Full Transparency)

Why we did this at all: a data residency requirement pushing us off the public API for a subset of traffic, plus a CFO who said, verbatim, "show me we'd save $200K/year or stop." This post is the document we showed him.

The model: Llama 3.1 70B Instruct — quantized to AWQ 4-bit for the cost runs, FP16 as the quality control. Our eval set confirmed 70B-class quality was sufficient for our workload (support drafting, summarization, internal copilots).

The traffic (replayed from our actual API logs from the prior 30 days):

Metric Value
Average load ~340 requests/min
Peak load ~1,300 requests/min (3 hours/day, business-hours peak)
Token mix 65% short (<500 total), 30% medium (500–2K), 5% long (2K–8K)
Avg prompt / completion 380 / 240 tokens
Total volume ~9.1B tokens over 30 days (~303M/day)

The hardware: AWS P5 instances (H100 80GB). Two facts that changed our math versus every 2024-era blog post: P5 now comes in single-GPU sizes (p5.4xlarge), so you can scale at 1-GPU granularity instead of 8 — and on-demand pricing has dropped to $6.88/GPU-hr, with spot around $2.30/GPU-hr in us-east-1.

The stack: vLLM 0.21 on EKS (Kubernetes 1.33), KEDA for queue-depth autoscaling, Prometheus + Grafana, LiteLLM as the gateway in front of everything.

Methodology: we had the OpenAI baseline from the prior month's real bill. Weeks 1–2 ran configs B and C against mirrored production traffic; weeks 3–4 ran config D live. All figures normalized to 30 days at the traffic profile above. Yes, normalization is a judgment call — the raw data is in the appendix repo so you can re-cut it.


The Cost Breakdown: 4 Configurations, 30 Days

First, the unit economics everything derives from:

Rate Value Source
H100 on-demand (p5, us-east-1) $6.88/GPU-hr AWS pricing, June 2026
H100 spot (p5, us-east-1) ~$2.30/GPU-hr ~67% discount, varies daily
OpenAI blended (our mix, with prompt caching) $5.20/M tokens Our actual bill ÷ our actual tokens

And the results:

Config Compute Other (EKS, networking, storage) Total $/1M tokens vs. API
A. OpenAI API (the gpt-4o-class model we were already on) $0 $0 $47,200 $5.20 baseline
B. Self-host FP16, on-demand (~20 GPUs avg, TP=4 replicas) $98,400 $3,100 $101,500 $11.18 +115%
C. Self-host AWQ 4-bit, on-demand (~12 GPUs avg, 1 GPU/replica) $61,500 $3,100 $64,600 $7.12 +37%
D. Self-host AWQ, 60% spot mix (~10 GPUs avg + API burst-shed) $29,200 $3,400 $32,600 $3.59 −31%

You can verify the arithmetic: config B is ~20 GPUs × 720 hrs × $6.88 ≈ $98K. Config D's blended rate (0.6 × $2.30 + 0.4 × $6.88 = $4.13/GPU-hr) across ~10 average GPUs ≈ $29K. Naive self-hosting (config B) was more than double the API. Quantization closed half the gap. Spot closed the rest and went past it.

The honest conclusion up front: config D's 31% savings were real, but came with strings attached —

  • 4 spot interruption events that degraded service, each handled by shedding traffic to the API
  • 18 hours of engineer time tuning KEDA and rebalancing the spot/on-demand mix mid-month
  • Capital allocation risk: a cluster is a commitment; the API is pay-as-you-go

And one string most posts hide entirely, which gets its own section.


The Hidden Costs Nobody Talks About

Eight costs that never show up in the GPU calculator:

Hidden cost What it actually was Damage
Setup engineering 3 weeks of one senior engineer: EKS GPU node groups, vLLM tuning, KEDA, gateway, dashboards ~$15K loaded cost
Ongoing maintenance ~6 hrs/week: patching, vLLM upgrades, spot rebalancing, model updates ~$3K/month
Quantization quality tax AWQ 4-bit scored 2–3% below FP16 on our eval set — which we had to build first, because we didn't have one 1 week of eval-pipeline work
Cold starts First request after scale-down waited 3–8s; fixed with a 2-replica warm floor ~$1K/month in idle GPU
Failure modes Spot reclaim means you need the API fallback anyway — so you're paying both bills, always API minimum spend retained
Observability tax 3 new Grafana dashboards, 2 PagerDuty alerts, 1 nightly evals job Days, not hours
Opportunity cost That senior engineer shipped zero features for 3 weeks The cost your CFO actually cares about
Compliance review New infra = new SOC 2 controls + a new audit-log pipeline; 2 weeks elapsed with security Calendar time, launch delay

Now redo the month-one math honestly:

Config D cloud bill:        $32,600
Setup engineering:          $15,000
Eval pipeline + obs + ops:  $15,000+
─────────────────────────────────────
Real month-one total:       ~$63,000

OpenAI, same month:          $47,200

Self-hosting was 33% MORE expensive in the first 30 days. The setup costs are one-time, though: at steady state (cloud $32.6K + ~$3K ongoing ops vs. $47.2K API), the gap is ~$11.6K/month — break-even lands around month 3 if traffic holds. That's the sentence your manager needs, and it's also the sentence the "90% cheaper!" posts and the "just use our API" posts both omit.


The Hybrid Architecture That Actually Wins

By day 30 we weren't running config D pure. We landed here:

                       ┌────────────────────────┐
   all traffic ───────▶│  LiteLLM gateway       │
                       │  health checks · cost- │
                       │  aware routing rules   │
                       └─────┬──────────────┬───┘
                     ~70%    │              │   ~30%
                  ┌──────────▼─────┐   ┌────▼──────────┐
                  │ TIER 1         │   │ TIER 2        │
                  │ vLLM 70B AWQ   │   │ OpenAI API    │
                  │ EKS, 60% spot, │   │ burst + spot- │
                  │ 2-replica warm │   │ recovery +    │
                  │ floor, 30s     │   │ peak overflow │
                  │ drain on       │   │               │
                  │ reclaim notice │   │               │
                  └────────────────┘   └───────────────┘

Tier 1 handles steady-state: ~70% of requests at an effective ~$0.0008/1K tokens. Spot nodes drain gracefully on the 2-minute reclaim notice (we trigger drain at 30s into it); the warm floor of 2 on-demand replicas carries the low-traffic overnight hours so we never cold-start.

Tier 2 is the API: peak-hour overflow and spot-recovery traffic. It pays for itself because it's what lets the cluster be sized for the median, not the peak — every GPU you don't buy for the 3 peak hours is pure savings.

The routing rules, in LiteLLM config:

model_list:
  - model_name: llm-prod
    litellm_params:
      model: hosted_vllm/llama-3.1-70b-awq
      api_base: http://vllm.inference.svc:8000/v1
  - model_name: llm-prod
    litellm_params:
      model: openai/gpt-4o          # same logical name → router decides
router_settings:
  routing_strategy: latency-based-routing
  health_check_interval: 5          # probe self-hosted every 5s
  fallbacks:
    - llm-prod: ["openai/gpt-4o"]
  cooldown_time: 60

Plus two custom pre-call hooks: shift 50% of traffic to the API when self-hosted p99 > 2s, error rate > 1%, or healthy replicas < 2 — and cost-aware routing that shifts to the API whenever the spot price spikes above 2× its baseline (at 2×, spot H100s cost more per token than the API does).

The month-end result of the hybrid:

Metric Pure API Pure self-host (D) Hybrid
Monthly cost $47,200 $32,600 (+eng) $44,800
Availability 99.99% 99.7% 99.94%

$44,800 looks like a modest $2,400 savings — but that's month one, while still paying the API for 30% of traffic and amortizing nothing. At steady state the hybrid tracks toward the mid-$30Ks while keeping API-grade reliability. The hybrid isn't a compromise between the two camps. It dominates both.


Decision Framework: Should YOU Self-Host?

Plug in your own numbers — our 303M tokens/day is the only input that makes our answer right for us:

  • Under 5M tokens/day → use the API. Don't think about it again. At this volume the engineering cost dominates everything; your "savings" are a rounding error against one senior engineer's week.
  • 5–50M tokens/day, AND you have a senior engineer with K8s + GPU experience → hybrid is probably worth it. Expect 20–40% savings after break-even, which takes a quarter.
  • Over 50M tokens/day → self-hosting with reserved capacity is a no-brainer on the math (3-year reserved H100s run ~$3/GPU-hr). But keep the API as fallback — that's just the hybrid again, weighted differently.
  • Data residency or compliance blocks the API outright → self-host, but budget 2× your estimate. Compliance was our single largest calendar-time cost.
  • No GPU/K8s experience on the team → use a managed open-model service (Together, Fireworks, Anyscale). You get open-model pricing without building the ops muscle — the legitimate middle ground.

What I'd Tell My Past Self

Don't trust the "90% cheaper" posts. Every one of them prices GPUs and excludes engineers. Our cloud bill dropped 31%; our month-one total rose 33%. Both numbers come from the same project.

Build the eval pipeline BEFORE you migrate. Migration took days. Knowing whether AWQ's 2–3% quality regression mattered took a week of building evals we should have had anyway. You cannot manage a quality regression you cannot measure.

Spot is great — keep at least 40% on-demand. Our 4 interruption events were absorbed only because the on-demand floor plus API fallback existed. A 100% spot cluster is a cost optimization that converts directly into an availability incident.

The hybrid is the actual answer for ~80% of teams. Self-host the predictable base, buy the unpredictable peak. Tribal "API vs. self-host" takes are arguing about which half of the architecture to delete.

Self-hosting isn't a cost optimization — it's a capability investment. The eval pipeline, the GPU autoscaling, the routing layer, the on-call literacy: you'll need all of it as AI workloads grow, whoever serves the tokens. The 31% was almost beside the point.


The Spreadsheets

All the raw data behind this post — billing CSVs, traffic logs, the vLLM/KEDA/LiteLLM configs, and the cost model as a spreadsheet you can plug your own traffic into — is in this repo: llm-selfhost-30days.

The numbers are reproducible. If you run a different setup and get different results, I genuinely want to hear about it — open an issue.


Summary

Question Answer
Is self-hosting cheaper? On the cloud bill: yes, −31% (with spot + AWQ). All-in, month one: no, +33%.
When does it break even? ~Month 3 at our volume (303M tokens/day), if traffic holds
What's the biggest hidden cost? Engineering time — ~$30K in month one that no GPU calculator shows
What actually won? Hybrid: self-hosted base + API burst = $44,800/mo at 99.94% availability
Should you do it? <5M tokens/day: no. >50M: yes, with API fallback. Between: only with K8s+GPU skills in-house.

The one-line version: self-host the base, buy the burst, and count the engineers.

Discussion

Have thoughts on this post? Share them below — questions, corrections, or your own experience are all welcome.