Teams usually try to reduce LLM API costs by looking for a cheaper line item, a smaller model, or a discount. The engineers who actually succeed treat it as an ordered procedure: measure first, remove waste, shrink what you send, move deferrable work to cheaper execution paths, stabilize caching, right-size models behind quality guardrails, and verify against the baseline you started with. The order matters because each later step depends on what the earlier ones prove. Skip measurement and right-size a model into a quality regression, and you will not be able to say what the savings were or where quality went. This guide is the hub for that sequence, and every mechanism it references is covered in depth in the sibling articles linked step by step.
Step zero: measurement and API cost attribution
Nothing else starts until you can answer one question in a sentence: which features consume the bill? An LLM cost optimization program without measurement is guessing, and guessing produces the two classic failure modes: cutting something that was not the problem, or breaking quality to save something that was rounding error. Build the baseline from three signal groups. First, spend and usage grouped by feature, team, and customer, so the biggest line items are visible, using the attribution approach from the usage and cost tracking guide. Second, cache-related usage fields, because they tell you whether caching is working at all before you touch it. Third, retry counts and rejected-request rates, because some of what looks like demand is actually waste, as covered in the retry budgets guide. Write the baseline down. Every later step will be judged against it.
Step one: eliminate waste before optimizing anything
The cheapest token is the one you never send, and the most common cost problems are waste, not pricing:
- Retry storms. Applying backoff-retry to errors that are not retryable, such as the 403 family or hard spend limits, re-sends requests that will never succeed. Worse is stacked retry: an SDK with automatic retries plus an application-level retry wrapper can multiply request volume per logical call. Test your stack for nesting.
- Silently broken caching. If a timestamp or random ID sits in your prompt prefix, or dynamic content is placed before stable content, or tool definitions are tweaked on every deploy, the cache never hits. You then pay a fresh cache write on every request and never get a read. The mechanisms are in the caching guide, and the pattern is worth an explicit check.
- Runaway agent loops. Tool definitions occupy prompt space, and every loop iteration re-sends the growing conversation. A loop without a round limit and without a token budget is an open tap; the tool calling guide covers the loop design.
- Repeated context. The same long document pasted into many calls, when a cached prefix or a document reference would do, is pure repetition.
Step two: shrink the tokens per request
OpenAI's cost optimization guide groups the levers into three strategies: reduce requests, minimize tokens, and select a smaller model. It also notes that cost and latency are connected, so most of this work pays twice. Concretely: merge calls that always travel together into one request instead of two; cap output length where a long answer serves nobody, since output is the expensive direction; ask for structured output containing only the fields the downstream code actually reads; and drop context that does not change the answer. Output length limits are also a reliability feature: a bounded answer is easier to validate, and validation costs nothing.
Step three: batch API vs flex processing for deferrable work
Some work does not need an immediate response, and that fact should be priced. Two official paths exist:
- Batch APIs. For OpenAI, the Batch API processes jobs asynchronously: you collect requests into a single file, kick off a batch job, query its status while requests execute, and retrieve the collected results when it completes. For Anthropic, the Message Batches API works the same way: submit many requests for asynchronous processing, poll for status, retrieve when done. Most batches finish in less than 1 hour, you can access results when all messages complete or after 24 hours (whichever comes first), and batches expire if processing does not finish within 24 hours. The fit test is simple: high volume, no immediate response needed, tolerant of an hour-scale turnaround.
- Flex processing. OpenAI's cost guide describes flex as significantly lower cost for Chat Completions or Responses requests, in exchange for slower response times and occasional resource unavailability, positioned for non-production or lower-priority work such as model evaluations, data enrichment, or asynchronous workloads. The boundary writes itself: user-facing interactive traffic does not belong here, because occasional unavailability is a product decision, not an engineering detail.
Step four: prompt caching TTL, fixed properly
Caching is the step where order-of-operations discipline pays off, and where small mistakes destroy the benefit. The rule from Anthropic's prompt caching documentation: the cache references the entire prompt, tools, system, and messages in that order, up to and including the block you designate. So the design principle is stable-first: put the content that rarely changes at the front, move volatile content behind the breakpoints, and place explicit markers where stability ends. Two details bite teams that treat caching as a set-and-forget switch. First, the TTL defaults to 5 minutes, and a 1-hour option exists at additional cost, with guidance to keep the 5-minute default for prompts used more frequently than every 5 minutes (it keeps refreshing) and reserve the 1-hour variant for prompts used less often than 5 minutes but more often than hourly. Second, the edge cases: if the last block already carries an explicit cache marker with the same TTL, automatic caching is a no-op, and if the marker has a different TTL, the API returns a 400 error. Cache writes and cache reads are priced differently from base input tokens, and the multipliers stack with other pricing modifiers, so pricing math belongs on the official pricing page, not in an estimate. One more operational note: cache hits are not deducted against your rate limit, so fixing caching improves headroom as well as cost. The mechanics, including how to verify hits from usage fields, are in the caching in practice guide.
Step five: smaller models, with quality guardrails
The third official strategy is selecting a smaller model, which OpenAI frames as balancing reduced cost and latency with maintained accuracy. "Maintained" is the operative word, and it does not happen by accident. Pick models by the constraints of each task rather than by reputation, using the framework from the model selection guide: what accuracy, latency, and capability does this specific workload actually need? Then keep the guardrail: a regression suite that runs the same tasks against the smaller model and compares outputs against the current baseline, so a downgrade is a measured decision rather than a silent one. Quietly trading quality for cost is the worst trade available, because the bill falls while the product degrades, and nobody can attribute which change did which.
Step six: verify against the baseline
Every action above is a hypothesis until step zero's baseline confirms it. Close the loop with three checks, evaluated together, never one alone:
- Cost curve. Does spend per feature and per team actually trend down after the change?
- Cache behavior. Did hit rates rise, or did a prefix change silently zero them out?
- Quality. Refusal rates, validation failure rates, and a sampled human review of outputs, compared against the same sample before the change.
If any of the three worsens, revert that single action and keep the others. One change at a time is what makes attribution possible; that is the same discipline incident logging applies to evidence, moved one step earlier, to the decisions themselves.
That baseline loop is the cost-side version of pre-release model verification; the testing playbook describes the same discipline for model and prompt changes.
The order-of-operations checklist
- Measure first: spend by feature, cache fields, retry and rejection rates. Write the baseline down.
- Kill waste: no retry on non-retryable errors, no stacked retry layers, no unstable cache prefix, no unbounded agent loops, no repeated context.
- Shrink tokens: fewer requests, shorter outputs, tighter schemas, less irrelevant context.
- Move deferrable work: batch APIs for high-volume asynchronous jobs; flex for non-production or low-priority loads; never for interactive traffic.
- Fix caching with the TTL details: stable-first prefixes, explicit breakpoints, aware of the no-op and 400 edge cases, with pricing math on the official page.
- Right-size models against a regression suite, not against a hope.
- Verify all three signals afterward, and revert anything that regresses one of them.
- Keep the rollback switch: every step above should be a configuration change you can undo on its own.
That is the whole trick. The teams that win at spend treat it as an engineering sequence with a measurement at both ends, and the endpoint-level facts for whatever endpoint you call are in the platform's own documentation.