Skip to content
mlmentorship

How to think about LLM inference cost

Count each billed model call once, including cache state, outputs, tools and retries; compare complete cost under quality and authority limits.

Published · 9 min read ·Role-specific ·Advanced
Reading depth

One user request can trigger many billed calls; count each once before diagnosing repeated context, retries or expensive tails.

Problem

Three model calls consume 1,200, 1,400 and 1,600 input tokens, plus 200 output tokens each. Each input includes the same 1,000-token prefix. The first use is uncached; the next two receive a prefix discount. Tools cost 0.001 dollars in total.

Use fictional prices per million tokens: 1 dollar uncached input, 0.2 cached input and 4 output. There are no additional cache-write charges in this example. Compute the request total and compare it with the same calls without caching. These are teaching prices, not current provider quotes.

Picture: Price Three Rows, Not Five Overlapping Buckets

CallTotal inputCached inputUncached inputOutputModel cost, dollars
11,20001,2002000.0020
21,4001,0004002000.0014
31,6001,0006002000.0016
Total4,2002,0002,2006000.0050

The prefix and history are already inside each input count. Do not add them again as separate token charges. Add tools once: the full request costs 0.006 dollars. Without caching, it costs 0.0076 dollars; the saving is about 21.05%. The 80% cached-token discount does not apply to the entire request.

Input tokens, not currency

Caching discounts repeated input, not newly generated output

Caching discounts repeated input, not new output at every callEach agent call can generate billable output. Repeated cached context changes one cost component, not the whole multi-call total.Each call retains input cost and addsfresh generated outputCall 1cached inputfresh outputCall 2cached inputfresh outputCall 3cached inputfresh outputCaching discounts one component; itdoes not zero the total.
Derivation
Three input bars show 1,200, 1,400 and 1,600 tokens Each input bar contains a 1,000-token stable prefix and respectively 200, 400 or 600 other input tokens. Prefix width is 180 units; the other widths are 36, 72 and 108, so total lengths scale exactly with token counts. Call one prices the prefix as uncached; calls two and three price it as cached. Each call also has 200 output tokens, priced separately and not included in the input bars. An extra call adds a ledger row with its own actual cache and output usage. ONE USER REQUEST CALL 1: 1,200 IN + 200 OUT 1,000 prefixuncached other200 CALL 2: 1,400 IN + 200 OUT 1,000 prefixcached other400 CALL 3: 1,600 IN + 200 OUT 1,000 prefixcached other600 Extra call: another rowprice its actual usage
each input bar repeats 1,000 prefix tokens. Other input grows from 200 to 400 to 600 tokens. Widths represent token counts, not cost. The 200 output tokens per call are separate. Another call adds its actual usage, not an assumed full-price retry.
Check: Which parts of calls 2 and 3 receive a cache discount? Why is their output still charged separately?
Read it this way: Each agent call can generate billable output. Repeated cached context changes one cost component, not the whole multi-call total.
Which cost component repeats freshly even when all three inputs are cached?

A Practical Cost Model

For each call, input is partitioned into uncached and cached tokens. Rates below have currency-per-token units; add explicit write/tool charges and allocated costs only once.

from decimal import Decimal


def model_cost(calls):
	total = Decimal("0")
	million = Decimal("1000000")
	for call in calls:
		input_tokens = call["input_tokens"]
		cached = call["cached_input_tokens"]
		output = call["output_tokens"]
		if not 0 <= cached <= input_tokens or output < 0:
			raise ValueError("invalid token partition")
		total += (
			Decimal(input_tokens - cached) * Decimal("1")
			+ Decimal(cached) * Decimal("0.2")
			+ Decimal(output) * Decimal("4")
		) / million
		total += call.get("cache_write_cost", Decimal("0"))
	return total


calls = [
	{"input_tokens": 1200, "cached_input_tokens": 0, "output_tokens": 200},
	{"input_tokens": 1400, "cached_input_tokens": 1000, "output_tokens": 200},
	{"input_tokens": 1600, "cached_input_tokens": 1000, "output_tokens": 200},
]
assert model_cost(calls) == Decimal("0.005")
assert model_cost(calls) + Decimal("0.001") == Decimal("0.006")

Reconcile request/call/attempt IDs, usage categories, cache state, rate version and tool receipts against billed totals. Include every retry, cancellation and failed task that incurred charges.

Change 1: Stable Prefixes Dominate

New task. Most input repeats an authorized prefix.

Picture and change. Measure eligible cache hits, not just repeated text. Check provider/model support, exact-prefix rules, expiry, write/miss charges and tenant isolation. Compare safe prompt trimming under the same evaluation.

Check. Cached input does not discount outputs, tools or newly added history. Authorization and source freshness still apply independently of cache reuse.

Use when. Measured eligible repeated work makes caching worthwhile.

Change 2: Long Agent Runs Dominate

New task. Retries and growing tool history make some tasks expensive.

Picture and change. Bound steps, retries, tokens, time and money at enforced limits. Summarize only while preserving source evidence, authority, unresolved effects and stop conditions. Charge the summary calls too.

Check. With first input and additional history tokens per step, cumulative input is

Our three-call ledger fits , , giving 4,200 input tokens. Bounded fixed-size context instead gives approximately linear cumulative input, excluding additional compaction work.

Use when. Measured multi-call tails dominate spend. An exhausted run is incomplete, not a cheap success.

Preserve Release Requirements

Compare quality, severe failures, authority, latency and cost per successful task on the same population. Keep a rollback for prompt, routing, retrieval, model and budget changes. Lower cost can come from removing waste or from losing useful work; distinguish them.

Failure: Charge the Same Work Twice

Prompt and retrieval tokens cannot be added again after counting full input. Actual tail calls already appear in the ledger; do not add another arbitrary tail charge. A dimensionless multiplier cannot be added directly to currency.

Transfer Check

Must cumulative input grow quadratically with the number of calls?

Reasoned Answer

No. Quadratic growth requires each call to resend roughly linearly growing history. Fixed-size context can grow approximately linearly, and cache pricing changes cost separately from token count.

The Five Layers of Cost

Treat these as diagnostic views of one ledger, not five additive charges.

Layer 1: Per-Request Token Cost

Separate input/output rates and usage classes. Benchmark smaller models, distillation, quantization and batching under the same quality/latency requirements. Price ratios and savings depend on the actual service.

Layer 2: Prompt Amortization

Measure repeated instructions, examples and schemas. Compare trimming, eligible caching and adaptation, including training, refresh and validation costs. For example, 5,000 system tokens plus 100 query tokens make the system portion about 98% of uncached input. That is not 98% of the full bill.

Layer 3: Retrieval / Context Overhead

Measure retrieved passages, conversation history and tool results. Reranking, field selection and compression can reduce tokens but add compute or remove necessary evidence. Validate both effects; fewer chunks are not automatically better.

Layer 4: Multi-Step / Agentic Cost

Measure planning, tools, verification, synthesis and retries separately. Evaluate smaller-model routing and safe parallel work without speculating unauthorized or irreversible side effects. Concurrent calls still consume resources and money.

Layer 5: Tail Cost

Inspect p50/p95/p99, cohort sizes, completion and expensive traces. Apply input/output/step caps and tenant quotas; prompt wording alone is not a hard limit. Forecast tails with explicit assumptions rather than claiming universal percentile multipliers.

Changes Can Interact

Shorter context can reduce input work yet worsen answers and increase retries. Evaluate complete request economics, not independent percentage reductions multiplied without evidence.

Self-hosted cost uses allocated accelerator capacity/time, utilization, memory, networking and operations. Do not charge the same work both a hypothetical API token bill and its hosting cost. Distinct external calls can still add real API charges.

Provider References

Verify current dated pricing and cache semantics before applying any real rate.

Related: Designing a RAG system that actually works, When would you fine-tune vs prompt vs RAG?.