, ,

How to Reduce LLM API Costs, From Prompt Hygiene to Self Hosting

A practical, beginner to expert guide to cutting LLM API costs: token math, prompt and context hygiene, caching and batching, model routing, and when self hosting actually pays off.

AI Engineering · Reducing LLM Cost

A startup I advise burned eighty percent of a quarterly API budget in the first nineteen days, then spent the rest of the quarter rationing calls and apologising to customers. Almost none of it was the model being expensive. It was one bloated system prompt shipped on every request, no caching, a frontier model answering questions a small one would have nailed, and a retry loop that quietly doubled the bill on every timeout. Each of those is fixable in an afternoon. This guide walks the whole cost surface, from the token math a beginner needs through the self hosting economics an expert argues about, and gives you an order to attack it in so you cut the most money for the least effort first.

Key takeaways: Four levers move almost all of an LLM bill: how many tokens you send and receive, how much work you reuse through caching and batching, which model answers each request, and where the model runs. Attack them in that order. Prompt and context hygiene plus caching are cheap, fast, and routinely halve spend. Model routing adds another large slice. Self hosting only pays back at real volume. Cached reads bill around ten percent of the normal input rate, batch processing takes fifty percent off, and routing saves teams forty to seventy percent in production. Stack them and a ninety percent cut is ordinary, not remarkable.
Who this is for: Anyone paying for LLMs and watching the bill climb, from a solo developer on a first API key to a platform team running millions of calls a day. No prior cost work assumed. Terms on first use: a token is roughly three quarters of a word, the unit you are billed in; input tokens are what you send (prompt plus context), output tokens are what the model generates and usually cost several times more; the context window is the maximum tokens a model can read at once; prompt caching stores a processed prefix so repeat calls skip re reading it; batching submits many requests together for a discount; RAG, retrieval augmented generation, fetches only the relevant text instead of stuffing everything in; quantization shrinks a model to cheaper numeric formats so it runs on less hardware.
~90% off
cached input reads vs normal rate
50% off
batch processing, async within a day
40 to 70%
typical saving from model routing

Where the money actually goes

Before you cut anything, understand the meter. Almost every hosted LLM bills the same way: cost equals input tokens times the input price plus output tokens times the output price, quoted per million tokens. Two facts about that formula drive every decision below. First, output usually costs several times more than input, often three to five times, so a chatty model that pads answers is more expensive than its input footprint suggests. Second, the API is stateless, which means you resend the full context on every single call. That forty thousand token document you attach is not paid once, it is paid on every turn of the conversation until you remove it.

Two more multipliers hide in production. Retries on timeouts or rate limits can double or triple real spend while looking like normal traffic in your code. And model tier swings the unit price by more than an order of magnitude, so the single biggest lever for many workloads is simply not sending every request to the most expensive model. The chart below shows the spread with round illustrative numbers; your provider will differ, so read it for the shape, not the exact figures.

Unit price swings by more than ten timesillustrative price per million input tokens, check your provider for exact ratesFrontier model~$5.00Cached frontier read~$0.50Mid tier model~$1.00Small model~$0.15
Two moves in the same picture: drop to a smaller model where you can, and cache the frontier prefix where you cannot. Both cut the same bar.
Cost driverWhy it adds upLever that fixes it
Output tokenspriced several times higher than inputcap length, ask for structured or terse answers
Resent contextfull prompt billed on every stateless calltrim, summarize history, cache, retrieve
Model tierfrontier costs ten times a small model or moreright size and route per request
Retriessilent duplicate calls on timeout or rate limitbackoff, idempotency, cap retry count
Idle context windowlarge windows tempt over stuffing you pay forretrieve only what the task needs

Measuring and attributing spend

You cannot cut what you cannot see, and the default provider dashboard hides the one number you need most, which is cost per feature. Log input and output token counts on every call, and tag each one with the feature or endpoint that made it, the model used, and whether it hit the cache. Roll that into a plain cost per request and cost per feature view, refreshed daily. Most teams find that a handful of endpoints drive the majority of spend, and that a single background job nobody thought about is the quiet leader. Attribution turns a frightening aggregate into a short, ranked list of things to fix, which is exactly what you want in hand before you touch a single line of code.

# Emit token usage per call, tagged so you can attribute cost later log.info("llm_call", feature="support_reply", model=model_name, input_tokens=usage.input_tokens, output_tokens=usage.output_tokens, cache_hit=usage.cache_read_input_tokens > 0)

Then set budgets and alerts so a runaway loop cannot bill all weekend before anyone notices. A hard monthly cap per environment, a spend rate alert that fires when hourly cost jumps past a threshold, and a per request token ceiling together catch the failure modes that otherwise arrive as a shocking invoice at month end. Treat token usage as a first class metric alongside latency and error rate, because in an LLM system it behaves like one, and the teams that watch it in real time are the ones that never get the nasty surprise.

Prompt and context hygiene, the cheapest win

Start here because it costs you nothing but attention and it touches every call you make. Most prompts carry dead weight: a system message that grew by accretion, half a dozen few shot examples where two would do, an entire chat history resent verbatim when a short summary would carry the same meaning. Trim the system prompt to what changes behaviour. Prune few shot examples to the smallest set that holds quality on your eval. Replace a growing transcript with a rolling summary once it passes a few turns. None of this is glamorous and all of it compounds on every request for the life of the feature.

Output is the other half. Set a real max token limit so a model cannot wander into a thousand token essay when you needed a sentence. Ask for structured output, JSON or a fixed schema, which is both cheaper and easier to parse. One team documented cutting average response length from four hundred tokens to two hundred eighty just by specifying a structured format, part of a seventy one percent monthly cost reduction with no visible drop in quality. Use stop sequences to end generation the moment the useful part is done. These are one line changes with outsized returns.

# Cap output, ask for a tight schema, stop early resp = client.messages.create( model="small-fast-model", max_tokens=280, # hard ceiling on the expensive half system=STABLE_SYSTEM_PROMPT, # trimmed, no per-call junk stop_sequences=["nn"], messages=[{"role":"user","content":user_msg}], )
Contrarian note: A bigger context window is not a free lunch, and the common advice to just use a long context model instead of building retrieval gets this wrong. You pay for every token in that window on every call, and long contexts also degrade accuracy as the model loses the thread in the middle, a failure often called context rot. Retrieve what the task needs, do not stuff the window because it is there. Cheaper and more accurate point the same direction here.

A few more habits pay off quietly. Compress long instructions into crisp directives, since the model does not reward verbosity in the prompt the way a human reader might. Trim tool and function schemas to the fields you actually use, because those definitions ride along on every call that offers the tool. Avoid repeating the same instruction in both the system and the user message, a common duplication that pays twice for the words that matter least. And prefer references over inlined examples where the model already knows the pattern, so you are not teaching it something it learned in pretraining.

Caching and batching, reuse what you already paid for

If any part of your prompt repeats across calls, and for most applications the system prompt, tool definitions, and reference documents repeat on every single request, you are paying to process the same tokens again and again. Prompt caching fixes exactly that. The provider stores the processed prefix, and subsequent calls that share it read at a steep discount, commonly around ten percent of the normal input rate. Writing to the cache costs a small premium, roughly one and a quarter times input, and the entry lives for a few minutes by default with a longer option available. The rule that makes or breaks it: put stable content first and volatile content last, so the cacheable prefix stays identical call to call.

# Mark the stable prefix as cacheable, keep the volatile user turn after it system=[ {"type":"text", "text": LONG_STABLE_CONTEXT, "cache_control": {"type":"ephemeral"}}, # cached prefix ] messages=[{"role":"user", "content": todays_question}] # not cached

Two neighbours of caching finish the job. Semantic caching stores answers keyed by meaning, using an embedding match, so a question you have effectively answered before is served from your own store without an LLM call at all, ideal for FAQ style traffic. And batching takes work that does not need an instant answer, evaluation runs, nightly backfills, embeddings, report generation, and submits it asynchronously for a flat fifty percent discount, with completion guaranteed within a day and usually much faster. Caching and batching are independent discounts that stack, which is how effective input spend on repetitive pipelines drops by ninety percent or more.

TechniqueLatencyRough savingBest for
Prompt cachingfasterup to ~90% on the cached prefixrepeated system prompt, docs, tools
Semantic cacheinstant on hit100% on a cache hitrepeated or near duplicate questions
Batch APIminutes to a day50% flat, stacks with cachingevals, backfills, embeddings, digests
War story: I once turned on prompt caching for a support assistant and the bill barely moved. The cache hit rate sat at two percent. The cause took an afternoon to find: a helpful engineer had injected the current timestamp at the very top of the system prompt for logging, so the cacheable prefix was different on every single call and nothing ever matched. We moved the timestamp into the user turn at the end, the hit rate jumped to eighty eight percent, and input cost fell about seventy percent overnight. Caching is unforgiving about prefix stability. One volatile token at the front throws the whole discount away.

Model selection and routing, right size every call

Once your prompts are lean and cached, the next big lever is refusing to pay frontier prices for work a cheaper model does correctly. Default to the smallest model that clears your evaluation on a task, and escalate deliberately rather than reaching for the biggest model out of habit. There are three ways to decide per request. A cascade tries the cheap model first and escalates only when confidence is low, which is excellent for asynchronous and throughput work but adds the cheap model latency to every escalated request, so it can be the wrong choice on an interactive path. A classifier router predicts the right model before any call, so it pays no escalation penalty and suits interactive traffic. And distillation fine tunes a small model on a larger model output for one narrow task, giving near frontier quality at small model prices where the task is stable.

The savings are real and well documented. Teams routing in production commonly report forty to seventy percent lower cost at equal quality, and the FrugalGPT research showed a cascade reaching up to ninety eight percent reduction against a frontier only baseline on several benchmarks. The catch is that routing on quality requires measuring quality first, so you need an eval before you can trust a router. Build that eval, then let it pick the cheapest model that passes.

flowchart TD
  U[Incoming request] --> C{Rules or classifier}
  C -->|Simple, factual| S[Small model]
  C -->|Standard task| M[Mid model]
  C -->|Hard or high stakes| F[Frontier model]
  S --> V{Confidence ok}
  V -->|No| M
  V -->|Yes| O[Return answer]
  M --> O
  F --> O
A tiered router: a cheap rules or classifier pass decides first, a confidence check catches the small model misses, and only genuinely hard requests reach the frontier tier.
Verdict: For interactive apps, prefer a classifier or rules router that decides before calling, so users never wait through a failed cheap attempt. Reserve pure cascades for batch and throughput pipelines where the extra hop does not hurt anyone. The one to avoid is sending everything to the frontier model by default, which is the most expensive habit in the whole stack.

Retrieval, infrastructure and self hosting

The advanced levers change the shape of the workload itself. Retrieval augmented generation is a cost technique as much as a quality one. Instead of pasting an entire knowledge base into the prompt, you index it, retrieve only the handful of chunks relevant to the question, and pass those. One documented setup dropped average input from a stuffed window to about eight thousand tokens by retrieving the ten most relevant chunks, roughly a six times reduction in input cost, with better answers because the model was not distracted by irrelevant text. Deduplicate near identical chunks, and where chunks are long, summarize them with a cheap model before handing them to the expensive one.

Self hosting is the lever everyone reaches for too early. Running an open weight model on your own hardware removes the per token markup, but adds fixed hardware, engineering, and operations cost that people consistently underestimate. The break even depends entirely on volume. Below roughly twenty million tokens a month, managed APIs almost always win once you count the ops time. Between fifty and one hundred million tokens a month is where a seventy billion parameter class model starts to pay back. Above one hundred million tokens a month, self hosting usually wins on unit economics. Quantization tilts the math further: moving to an eight bit format on a modern GPU can roughly double throughput at the same hourly cost, bringing cost per million tokens from around a dollar ninety to near a dollar. Serve with an engine built for it, and benchmark before you commit.

Monthly volumeCheapest pathWhy
Under ~20M tokensmanaged APIops overhead dwarfs any per token saving
~50 to 100M tokensbreak even zoneself hosting a 70B class model starts to pay back
Over ~100M tokensself host, quantizedunit economics favour your own GPUs

If you cross into self hosting territory, the engine and the compression method decide your real cost per token. I have written the hands on detail elsewhere: how to shrink a model without wrecking quality in model compression and quantization, how to prove your throughput numbers in benchmarking a self hosted inference deployment, and how to scale it in distributed inference on Kubernetes. The wider engineering picture lives in the AI Engineering complete guide.

A pragmatic middle path beats a religious one. Many teams run a hybrid: self host the steady baseline load on their own quantized model where the volume justifies it, and burst to a managed API for spikes and for the hardest requests a small model cannot handle. You get the unit economics of owned hardware on predictable traffic without paying to provision for your worst hour. Route by both difficulty and current load, and let the expensive path absorb only what the cheap path cannot carry.

Agents and multi step workflows, the cost multiplier

An agent that plans, calls tools, reads the results, and tries again can turn one user request into twenty model calls, and each call resends the growing history. This is where bills surprise people, because cost scales with the number of steps, not the number of users. A single stuck loop can spend more in an hour than a thousand ordinary chats do in a day. Cap the number of steps a loop may take and fail gracefully when it hits the ceiling rather than spinning forever. Cache tool results so the same lookup inside one task is not paid for twice. Run independent tool calls in parallel instead of chaining them, since a chain resends the whole context on every hop and the context only grows.

Right sizing matters even more inside an agent than outside it. Use a small model for the routine steps, planning, routing, and formatting, and reserve the frontier model for the one or two steps that genuinely need its judgement. Summarize the working memory between steps instead of carrying the full transcript, so context does not grow without bound across a long task. An agent with a step cap, cached tools, parallel calls, and a small model on the routine work can cost a fraction of the same agent built naively, at the same success rate. If you run agents in production, this single section is often the largest line on the whole bill, so it deserves the most careful engineering.

A cost model you can run

Put a number on it before you optimise, because you cannot manage what you do not measure. Take a concrete workload: two million requests a month, six thousand input tokens and five hundred output tokens each, all hitting a frontier model. That is a baseline you can compute in a spreadsheet from your provider rates. Now apply the levers in order and watch the same workload shrink. Prompt and context hygiene trims input and caps output. Caching collapses the repeated prefix. Routing sends the easy majority to a small model. Batching halves the async share. The waterfall below shows the cumulative effect with illustrative percentages; the point is the shape, and the fact that the cheap first two levers already do most of the work.

Stacking the levers, cost vs baselineillustrative cumulative percentage of the original bill, your mix will varyBaseline100%+ Prompt hygiene~70%+ Caching~48%+ Routing~30%+ Batching~22%
Roughly four fifths of the bill gone, and more than half of that from the two levers that took the least work. Start at the top of this chart, not the bottom.

Try it on your own numbers

The calculator below runs the same model this section describes. Enter your usage, choose a model tier, then pull the caching and batching sliders and watch the monthly bill move. It also flags when your volume crosses into self hosting territory.

Common cost mistakes and their fixes

SymptomUsual causeFix
Caching on but bill flata volatile token at the top of the prefixmove dynamic content to the end, verify hit rate
Cost spikes with no traffic changeretry storms on timeouts or rate limitsexponential backoff, cap retries, log attempts
Output far longer than neededno max token limit, unstructured promptset max_tokens, request a schema, add stop sequences
Every call hits the frontier modelno routing, biggest model by defaultadd a classifier or rules router with an eval
Huge input on simple questionswhole knowledge base pasted into the promptretrieve top chunks with RAG, stop stuffing
Self hosting costs more than APIhosting below the break even volumestay on the API until you cross the volume line
Guardrail: Cheaper is not free if it costs you quality. Pair every optimisation with a small regression test on real prompts, and watch your quality metric next to the bill. A route that saves forty percent but quietly drops answer accuracy by ten points is not a saving, it is a refund you are handing customers in frustration. Cut hard where quality holds, and stop the moment it slips. The target is the cheapest bill at your quality bar, not the cheapest bill.

Your one week cost cut plan

Do this on Monday: Instrument first. Log input and output tokens per endpoint for a day so you know where the money actually is, because it is rarely where you guess. Then work top down: trim prompts and cap output on your busiest endpoint, enable prompt caching with the stable prefix first and confirm the hit rate climbs, move any non interactive job onto the batch API, and only then add a router with a small eval behind it. Leave self hosting alone until your metering shows you crossing roughly twenty to fifty million tokens a month. Verdict: spend your first week on prompt hygiene and caching, the two levers with the best return per hour, and treat self hosting as a volume decision rather than a default.

References

About The Author


Discover more from Journal of Intelligent Infrastructure

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure

Subscribe now to keep reading and get access to the full archive.

Continue reading