Learn how to reduce LLM API costs without sacrificing quality using model routing, prompt caching, token trimming, batching, and smart cost tracking.
LLM bills rarely creep. They step-function: a feature ships, usage doubles, a new agent loops five times per request, and suddenly the monthly invoice has an extra zero. Most teams are overpaying by 40–80%, and the fixes don't require sacrificing output quality. They require knowing which lever to pull, and in what order.
This is the practical playbook we use at Powabase to reduce LLM API costs on real production workloads: routing, caching, token discipline, batching, tighter RAG retrieval, and, sometimes, self-hosting. It's a supporting piece under our broader guide to designing token-efficient AI systems, so we'll stay tightly on cost.
Why LLM API costs climb faster than usage
The pricing math is not linear with users. Every new feature adds a system prompt, a tool schema, a retrieved context block, and often a multi-step agent loop where each step re-sends the growing conversation history. A single user question can become five or ten billed calls, each carrying the same 2,000-token preamble.
That's why cost-per-user drifts up even when signups are flat. It's also why the highest-leverage optimizations are structural (how you route, cache, and shape context) rather than per-token haggling. Cost optimization work commonly cuts LLM bills 30–80% without any change to model quality, because the waste is in the plumbing, not the model.
Start with a baseline
Before touching a single prompt, measure. Optimizing without a baseline means you'll congratulate yourself on savings you can't prove and miss the 20% of traffic that's driving 80% of the bill.
Track cost per request, per feature, and per customer
You want three numbers, tagged on every call: which feature triggered it, which customer it belongs to, and what it cost (input tokens × rate + output tokens × rate + any cached-read discount). A gateway or middleware layer that stamps these tags is the cleanest way to get there. Most cost blowups turn out to be one runaway feature or one power-user tenant, and per-customer cost attribution is the only way to see that.
If you're building on Powabase, our agent runs emit usage statistics per session, so per-feature and per-tenant attribution is a matter of tagging sessions. You're not standing up a separate telemetry pipeline.
Build a simple request taxonomy to find your biggest spend
Group your traffic into 4–6 buckets: classification, extraction, short Q&A, summarization, long-form reasoning, agentic multi-step. Price each bucket at current volume. The winner is almost always one of two things: a chatty agent that loops too many times, or a cheap-looking endpoint called millions of times a day. Those are your first two targets. Everything else can wait.
Lever 1: Route each request to the cheapest capable model
The pricing gap between a frontier model and a mid-tier one is not 2×. It's 10–20×, and the majority of production traffic doesn't need the frontier. Routing is the single highest-impact lever, and CloudZero's teardown of LLM cost optimization puts it first: route each request to the cheapest model that can handle it, because the first three levers deliver most of the savings for the least effort.
Task-based routing vs. semantic routing
Task-based routing is the pragmatic default. You know at call site whether the job is classification, extraction, summarization, or open-ended reasoning, so you pick the model tier in code:
- Classification, tagging, extraction, structured output — mid-tier is plenty. gpt-4o-mini at $0.60/M output tokens or a similarly priced Haiku-class model handles these cleanly.
- Short conversational replies and simple summarization — mid-tier with a quality eval to confirm.
- Complex reasoning, code generation with hard correctness bars, ambiguous multi-step planning — flagship, but only for the step that needs it.
Semantic routing (a small classifier decides model per request) is worth it once task-based routing has been squeezed. Powabase routes model IDs through LiteLLM, so switching a workflow's model is a string change on the model field, which makes A/B testing tiers cheap.
Does model routing actually save money? What FrugalGPT and RouteLLM show
The academic evidence is real. RouteLLM evaluated learned routers against a random-router baseline on MT Bench, training on preference data to decide when a weaker model was good enough, with the goal of minimizing cost at a fixed quality target. Earlier work on edge-vs-cloud routing found that a well-trained router could send 22% of queries to the small model with less than a 1% drop in response quality, and that was for large capability gaps, where routing is hardest.
Route based on measured task quality, not guesses. Use a small held-out eval set per workflow, compare tiers on quality, latency, cost, and failure modes, and only promote the cheap model where it clears the bar.
Lever 2: Stop paying twice with caching
Once traffic is routed, look at what you're paying to send repeatedly. Chatbots resend the same system prompt, tool schemas, and history on every turn. Agents resend a giant instruction preamble on every step. Prompt caching bills that repeated prefix at roughly 10% of the fresh rate, but only if the repeated part is a byte-identical prefix.
How prompt caching works on OpenAI, Anthropic, and Gemini
The major providers price and enable caching differently.
Which is "best" depends on traffic shape. Anthropic's 90%-off cached input pays for the 25% write surcharge after a handful of re-reads within the cache window, which is trivial to hit on any real chatbot. OpenAI is the easiest: no opt-in, no break-even math. Gemini shines for very large contexts reused for hours (think a 100-page document your users are all querying).
The universal discipline: put the stable stuff (system prompt, tool schemas, retrieved documents) at the front of the request, and put the volatile stuff (the user's new message, current timestamp) at the end. A timestamp in the system prompt silently invalidates every cache hit.
Semantic caching and the guardrails it needs
Prompt caching saves the input compute. Semantic caching skips the model call entirely: if a new question is close enough in meaning to one you've already answered, return the stored answer. It works well for FAQs, policy questions, and product docs, and it's a rounding error on latency compared to a fresh call.
The guardrails matter. Set a strict similarity threshold, scope the cache by tenant and permissions so one customer never sees another's answer, and expire aggressively for anything time-sensitive. Never semantically cache anything that touches personalized data, live account state, or answers that must be exact.
Lever 3: Trim tokens without trimming quality
Routing and caching handle the structural waste. Now attack the content of what you're sending.
Compress system prompts and apply a context budget
Most production system prompts have accreted over months: examples nobody validates, edge-case instructions for bugs that got fixed, redundant "be helpful" framing. Cut them. A tight 400-token system prompt with three good few-shot examples usually beats a 2,000-token one with twelve mediocre ones, and it's 5× cheaper on every uncached call.
Then enforce a context budget: a hard ceiling on how many tokens go into any single call, allocated across system prompt, retrieved documents, conversation history, and headroom for output. When a session approaches the budget, compact. Summarize older turns with a cheap model into a shorter representation. Powabase's agent runtime does this automatically. Before each LLM call it estimates tokens and, if near the limit, prunes old tool results and summarizes older conversation with a lightweight model like gpt-4.1-nano, keeping recent turns verbatim. The compaction model, keep-last-N, and output cap are all tunable.
Control output length and request structured output
Output tokens cost 3–5× more than input tokens on every major provider, so output token control has outsized leverage. Set max_tokens to a real ceiling, not the model's default. Ask for JSON with a schema when you need structured data; the model stops naturally instead of padding. Tell the model, in the system prompt, how long the answer should be ("respond in 2–3 sentences unless the user asks for detail"). Models comply with length instructions more reliably than most teams assume.
Lever 4: Batch anything that can wait
Any workload that doesn't need a synchronous response, like nightly report generation, bulk classification, backfilling embeddings on old records, or offline evaluation runs, belongs on a batch endpoint. OpenAI's Batch API and Anthropic's message batches both offer roughly 50% off list prices in exchange for up-to-24-hour turnaround. If you're paying real-time rates for a job that runs at 3am, you're leaving half the money on the table.
The pattern in practice: identify anything user-triggered but not user-blocking (weekly digests, moderation sweeps, re-embedding after schema changes), route it through a queue, and submit as a batch. On Powabase, workflows with scheduled starter blocks are the natural home for this. The scheduler fires on cadence, the workflow builds the batch, and results land back in Postgres.
Lever 5: Cut RAG context cost with tighter retrieval
RAG is a stealth cost center. Every retrieval typically injects 5–20 chunks into the prompt, and teams often set top_k high "just in case." That's tokens on every request, forever.
Three fixes, in order:
- Rerank aggressively and truncate. Retrieve 20, rerank with a cross-encoder, keep the top 3–5. Fewer, better chunks beat more mediocre ones on answer quality and cost simultaneously.
- Right-size chunks. 1,500-token chunks waste context on the 80% of the chunk that isn't relevant. Smaller chunks with good overlap retrieve more precisely.
- Cache the RAG preamble. If ten users ask about the same 100-page document, prefix caching turns that shared context into one paid computation instead of ten.
Powabase's knowledge base API exposes top_k and a context-token budget per request, and offers five indexing strategies with different cost profiles. For high-volume Q&A over stable docs, a leaner indexing strategy plus reranking usually beats maxing out chunk count.
When self-hosting or open-weight models beat the API
At some volume, API pricing stops being the cheapest option. The question is when.
The break-even math and the role of quantization
The napkin math that gets teams in trouble looks like: "We spend $15,000/month on the API. An A100 is $2/hour, so $1,440/month. We'd save 90%." That comparison ignores utilization, engineering time, reliability, and the cost of the surrounding stack. A GPU only saves you money if it's busy. A mostly-idle A100 is worse than API pricing.
The honest break-even for a self-hosted LLM lands around 2M–5M tokens/day of steady traffic on a workload that's a good fit: high-volume, predictable, low-latency-sensitive, and served by a model whose open-weight equivalent (Llama, Qwen, Mistral) matches your quality bar. Quantization (INT8, INT4) roughly doubles throughput per GPU and expands what fits on smaller hardware, which improves the math further, at some quality cost you need to measure on your own evals.
The realistic answer for most teams is hybrid: keep the API for low-volume, high-value, or bursty traffic, and route high-volume predictable tasks to self-hosted open-weight models. Powabase supports both sides of that split, with BYOK for OpenAI, Anthropic, Google, and OpenRouter on the API side, and self-hostable deployments for teams that want to run their own inference alongside their data.
How to protect quality while cutting costs
Every lever above can go wrong if you ship it without evals. The discipline is small and non-negotiable:
- Build a labeled eval set per workflow — 50–200 real requests with the answer you'd accept.
- Before promoting a cheaper model, cache, or shorter prompt, run the eval and record pass rate, not vibes.
- Ship the change behind a flag, monitor pass rate and user-visible signals (thumbs-down, escalation to human, retry rate) for a week.
- Roll back on regression. The savings only count if quality held.
Semantic caching and aggressive prompt trimming are where most quality regressions happen. Instrument them first.
Your cost-reduction playbook: stack the levers
The levers compound. Route 80% of traffic to a model that's 10× cheaper, and you've cut the bill dramatically. Cache the repeated prefix on what's left, and shave another 40–50%. Trim system prompts and cap output tokens for another 15–25%. Batch the offline jobs at 50% off. Tighten RAG top_k and rerank. What started as a $20k monthly bill lands closer to $3–5k, without a user noticing.
The order matters. Do them in the sequence above. Baseline and taxonomy first, so you know where the money is. Routing next, because it's the biggest lever to reduce LLM API costs and it changes what everything else operates on. Caching third, because it's cheap and near-instant. Then token discipline, batching, and RAG. Self-hosting last, only if the volume justifies the operational cost.
Start this week: tag every LLM call with feature and customer, price your top three request buckets, and move the highest-volume bucket to the cheapest model that clears your eval. That single change usually funds the rest of the work to reduce LLM API costs across the stack.