Updated July 2026

Practical rules for keeping LLM API bills sane. Prices below are Anthropic’s as of July 2026; the principles transfer to any provider.

Know the shape of the bill

Output tokens cost 5x what input tokens do. Per million tokens:

Model Input Output
Claude Fable 5 $10.00 $50.00
Claude Opus 4.8 $5.00 $25.00
Claude Sonnet 5 $3.00 $15.00
Claude Haiku 4.5 $1.00 $5.00

(Sonnet 5 is at an introductory $2.00/$10.00 through August 2026.)

Two consequences. First, a verbose model is expensive in a way a verbose prompt is not; trimming your prompt by 500 tokens saves cents, while stopping the model from writing a 2,000-token preamble saves real money at scale. Second, the gap between model tiers is large: routing a task from Opus to Haiku is a 5x cut on both sides of the ledger.

Use the cheapest model that passes your eval

Not the cheapest model that seems fine. Build a small eval set for each task (even 20 cases helps), then test down the tiers: if Haiku passes, use Haiku. Classification, extraction, formatting, and routing rarely need a frontier model. Save Opus-tier spend for the work that actually fails on smaller models: hard reasoning, long-horizon agent runs, subtle code review. A common production pattern is a cheap model as the front line with escalation to a bigger one on low confidence.

The same logic crosses provider lines. OpenAI and Google ship their own tiers with the same shape (frontier, mid, small), and for high-volume simple work a local open-weight model drops the marginal cost to electricity. The eval doesn’t care whose logo is on the model.

Cache your stable prefix

Prompt caching is the highest-leverage cost feature most people leave on the table. Cache reads cost about 0.1x the normal input price; writes cost 1.25x (or 2x for the 1-hour TTL). The catch is that it’s a strict prefix match: one changed byte invalidates everything after it.

The rules that follow from that:

  1. Stable content first. System prompt and tool definitions up front, per-request content last. The request renders as tools, then system, then messages, in that order.
  2. No timestamps or random IDs in the system prompt. A datetime.now() interpolated into your prompt silently disables caching for every request. Same for unsorted JSON serialization.
  3. Verify, don’t assume. Check usage.cache_read_input_tokens in responses. If it’s zero across repeated requests, something in your prefix is changing per request.
  4. Mind the minimum. Prefixes below a model-specific threshold (roughly 1-4K tokens) silently don’t cache at all.

For multi-turn conversations, caching the conversation history means each turn only pays full price for the new content. This is the difference between linear and quadratic cost growth as a session gets long.

Batch anything that can wait

The Message Batches API runs requests asynchronously at a 50% discount, with most batches completing inside an hour. Evals, backfills, bulk classification, nightly report generation: if nobody is staring at a spinner, it should be a batch. Half off for changing an architecture diagram, not a prompt, is the easiest win on this page.

Control the output side

Since output is the expensive direction, cap it deliberately:

  • Set max_tokens to what the task needs, not a reflexive maximum. A classifier doesn’t need room for an essay.
  • Use the effort parameter where supported. Lower effort produces fewer tool calls, less preamble, and terser output. The sweet spot depends on the model and the task: routine extraction, classification, and formatting often bottom out at low or medium, while agentic and coding runs on frontier models tend to want high or above. Find it with your eval rather than defaulting to one level.
  • Ask for the format you want. “Respond with only the JSON object” is a cost control, not just a style preference.

Keep context lean

Every turn of a conversation re-sends the entire history as input. Long agent sessions accumulate stale tool results and dead-end explorations that you pay to re-read on every subsequent call. Options, roughly in order of effort: cache the history (see above), clear old tool results once they’ve served their purpose, and use compaction (server-side summarization of earlier context) for sessions that approach the context window.

Measure before optimizing

Use your provider’s own token-counting endpoint (count_tokens for Anthropic, the tokenizer libraries OpenAI and others publish for their own models) to measure prompts; a tokenizer built for a different model family miscounts, sometimes by 15-20% or more. And read the usage block on real responses before deciding where the money goes: total prompt size is input_tokens + cache_creation_input_tokens + cache_read_input_tokens, so a small input_tokens number doesn’t mean a small prompt, it may mean caching is working.

The order to apply all this: measure first, cache second, batch third, downsize the model fourth, and only then start micro-trimming prompts. People tend to do it in exactly the reverse order.

For Claude Code specifically, token-audit is a local CLI that parses the session transcripts Claude Code writes to ~/.claude/projects/ and reports usage by project, model, and day. It’s the fastest way to find where your actual spend is going.