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
| Call | Total input | Cached input | Uncached input | Output | Model cost, dollars |
|---|---|---|---|---|---|
| 1 | 1,200 | 0 | 1,200 | 200 | 0.0020 |
| 2 | 1,400 | 1,000 | 400 | 200 | 0.0014 |
| 3 | 1,600 | 1,000 | 600 | 200 | 0.0016 |
| Total | 4,200 | 2,000 | 2,200 | 600 | 0.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
Derivation
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.
- OpenAI prompt caching.
- Anthropic prompt caching.
- Amazon Bedrock prompt caching.
- PagedAttention, a serving-memory design, not a provider pricing schedule.
Related: Designing a RAG system that actually works, When would you fine-tune vs prompt vs RAG?.