Cheat sheets

LLM Cost, Caching and Batch APIs

Price each call, cache prefixes and meanings, batch offline work and cap spend. Python and Rust from the lessons.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Comparisons
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Tasks#

TaskCode
Price one callcalculate_cost(model, input_tokens, output_tokens, cached_input_tokens=0)
Mark a cacheable block"cache_control": {"type": "ephemeral"}
Keep the block for one hour"cache_control": {"type": "ephemeral", "ttl": "1h"}
Read Anthropic cache hitsresponse.usage.cache_read_input_tokens
Read OpenAI cache hitsresp.usage.prompt_tokens_details.cached_tokens
Create a Gemini cacheclient.caches.create(model=<model>, config=...)
Use the Gemini cacheconfig=types.GenerateContentConfig(cached_content=cache.name)
Route a query to the cheapest modelroute_model(query, tier="pro")

From Lesson 11.11, 11.11 code/caching_cost.py, Lesson 11.15

Cache the stable prefix#

SYSTEM = [{
"type": "text",
"text": RUBRIC,stable text first
"cache_control": {"type": "ephemeral"},5 min TTL
}]
response = client.messages.create(
model="<model>", max_tokens=1024,
system=SYSTEM,
messages=[{"role": "user", "content": code}],variable text last
)
response.usage.cache_creation_input_tokenspaid at 1.25x
response.usage.cache_read_input_tokenspaid at 0.1x

From Lesson 11.15, Lesson 11.11

Numbers that matter#

Cache write
1.25x base for 5 min TTL. 2x base for 1 hour TTL.
Cache read
$0.30/M against $3.00/M fresh. Ten times cheaper.
Break-even
1 write and 1 read is 0.675x. 1 write and 10 reads is 0.205x.
Reuse rule
cache a block that you read 3 times or more in the TTL.
Batch
50% off input and output. 24 h guaranteed, 2 to 6 h typical.
Batch plus cache
about 10% of the sync uncached bill.
Model routing
saves 40 to 70% of model cost.
All levers stacked
about 5 to 10% of the naive baseline.

From Lesson 11.15, Lesson 17.14, Lesson 17.15, Lesson 17.27, Lesson 11.11

Budget guards in order#

1Rate limitper tenant at 2 to 3x expected peak. Returns 429with Retry-After.2Daily spend cap1.5 to 3x the contracted ceiling. Tighten therate and alert.3Kill switchspend z-score above 4 against the tenantbaseline. Auto-pause and page on-call.470% of budgetCostTracker adds a warning alert.585% of budgetthrottle. Route to cheaper models only.695% of budgetstop. Serve cached responses only.

From Lesson 17.27, Lesson 11.11, 11.11 code/caching_cost.py

Two cache layers#

embedhitmissprefixusageclientUser querystoreL1 semantic cacheembed, cosine 0.95+storeL2 prefix cacheprovider KV reusemodelModelfull price on a missCached responseno LLM callprocessCost trackertokens, cost,user_idembedhitmissprefixusageclientUser querystoreL1 semantic cacheembed, cosine 0.95+storeL2 prefix cacheprovider KV reusemodelModelfull price on a missCached responseno LLM callprocessCost trackertokens, cost, user_id

From Lesson 17.14, Lesson 11.11

Provider prompt caching#

FactorAnthropicOpenAIGemini
API stylecache_control markersAutomatic prefixCachedContent API
Hit price90% off input50% off inputAbout 25% of normal
Write cost25% surchargeNoneStorage per token·hour
Default TTL5 min, 1 hour optionUp to 1 hourUser-set, 1 hour
Min prefix1,024 tokens, 2,048 Haiku1,024 tokens4,096 Flash, 32,768 Pro
Use whenStable 10k+ prompt, many turnsServerless, no custom infraMulti-day reuse of a corpus

From Lesson 11.15

Defaults in the code#

SettingDefaultNote
similarity_threshold0.85SemanticCache. The demo uses 0.75
ttl_seconds3600Exact and semantic caches
max_size1000ExactCache. Evicts the oldest entry
temperature0.0Above 0 the exact cache skips
monthly_budget1000.0CostTracker alert base
spend_cap_multiplier2.0Cap is contract times this
kill_z_score4.0Pauses the tenant above it
Anthropic TTL5 min"ttl": "1h" for one hour

From 11.11 code/caching_cost.py, 17.27 code/main.py, Lesson 11.15

Submit a batch#

requests.append({
"custom_id": f"request-{i}",match results to inputs
"method": "POST", "url": "/v1/chat/completions",
"body": {"model": "<model>", "messages": [{"role": "user", "content": query}]},
})
batch_file = client.files.create(file=open("batch_input.jsonl", "rb"), purpose="batch")
batch = client.batches.create(
input_file_id=batch_file.id,
endpoint="/v1/chat/completions",
completion_window="24h",50% off, results in 24 hours
)

From Lesson 11.11

Troubleshooting#

SymptomCauseFix
Hit rate near 7%Time or request ID in the prefixPut dynamic text after the boundary
Parallel calls: N writesCalls beat the first writeSend request 1 alone, then the rest
cache_read_input_tokens stays 0Cache keys driftCheck both usage fields in CI
Block does not cacheUnder 1,024 tokens (2,048 Haiku)Make the cached block larger
OpenAI hits stop on deployTool reorder or new user fieldSerialize tools in a stable order
cached exceeds inputCached counted as extra tokensCached is a subset of input

From Lesson 17.14, Lesson 11.15, Lesson 11.11, token-counter-and-cost-meter/solution

Run the code#

CommandWhat it does
python main.pyRuns the lesson simulator in code/
python3 scripts/project_test.py <project> --stage 1 --path <workspace>Grades one stage
python3 scripts/project_test.py <project> --all --solution --strictGrades the reference solution
python3 <workspace>/usage.py <usage-file> --out usage-ledger.jsonReplays recorded usage into a ledger
python3 cli.py samples/input.json --mode execute --output budget.jsonRuns budget planner jobs

From 11.15 code/main.py, token-counter-and-cost-meter/README.md, agent-budget-planner/README.md, solution/cli.py

Project ledgers#

Rates
integer nano-dollars per token. Fixture inputs, not provider prices.
estimate
text.chars().count() over chars_per_token, rounded up. Ratio 0 is an error.
cost
usage.input - usage.cached at the input rate, plus cached and output. Each uses checked_mul.
reserve
spent + sum(holds) + amount > limit raises budget exceeded.
settle
actual above the hold raises actual cost exceeds reservation.
Statuses
completed, rejected, needs_reconciliation.
Sample run
190 units against a 100-unit limit. Two jobs pass. 95 units settle.

From token-counter-and-cost-meter/solution, token-counter-and-cost-meter/README.md, solution/main.py, solution/cli.py, agent-budget-planner/README.md

Q&A#

Prompt or semantic cache?
Prompt: same tokens. Semantic: same meaning.
Which semantic threshold?
0.92 to 0.95. At 0.85 wrong answers appear.
Which unit metric?
Cost per resolved query, not $/M tokens.

From Lesson 11.15, Lesson 11.11, Lesson 17.14, Lesson 17.15, Lesson 17.27

Tips#

  • Stamp user_id, task_id, route and tenant_id on every call.
  • Split tokens: prompt, tool, memory, response.
  • Gate deploys on read fraction above 80%.

From Lesson 17.27, Lesson 11.15