A DeepSeek API bill is not simply call count multiplied by a unit price. It is shaped by input tokens, output tokens, and whether those inputs hit the context cache. Plenty of teams budget from the published rates, launch, and then discover their actual spend is noticeably higher. The usual cause is not a price change; it is that their input structure, cache hit rate, and retry volume differ from the assumptions behind the estimate.

This article breaks DeepSeek API billing into pieces you can actually calculate: which tokens are charged, why caching works one day and not the next, how to estimate from the usage block in API responses, and what order to apply cost-saving measures. For current rates, check the model pricing page and DeepSeek's official documentation.

Note: DeepSeek is a trademark of its owner. This article reflects common API behavior as of October 2026. Prices, model names, and billing rules may change, so verify them on the official pages before purchasing.

1. Start by splitting the bill into four chargeable items

Charge When it applies Main drivers Optimization levers
Input (cache miss) New content enters the context for the first time Document length, chat history, tool definitions Retrieval, summarization, trimming
Input (cache hit) The request reuses a previously cached prefix Prefix stability, hit rate Fixed prefixes, fewer random elements
Output The model generates prose and structured results Output length, format constraints max_tokens, JSON constraints
Reasoning content A reasoning model produces its thinking Task difficulty, reasoning level Use non-reasoning models for simple tasks

DeepSeek's context cache generally shows up on the input side: a cached prefix is billed at a lower input rate, while the uncached portion is billed at the standard input rate. Whether there is a cache storage fee and how long cached entries persist depend on the current official documentation. Don't rely on rules quoted in older articles.

A single request can be written as one cost formula:

cost per request =
  cached input tokens × cache-hit price
+ uncached input tokens × input price
+ output tokens × output price

Until you put that formula into your logs, you cannot answer "what does this feature cost per month?" A single total on the billing dashboard rarely tells you which project or request type is inflating spend.

2. Why caching saves money, and why it often stops working

The basic idea behind context caching is straightforward: if the beginning of two requests is identical, the server can reuse earlier computation and only process the new portion. Caching is therefore most effective for:

  1. Fixed system prompts and role instructions.
  2. Stable tool definitions and function schemas.
  3. Knowledge-base excerpts, product manuals, and contract templates that are reused.
  4. The unchanging first half of a multi-turn conversation.

Conversely, the following patterns cause frequent cache misses:

  • Injecting the current time, a random ID, or a user nickname at the start of the system prompt.
  • Reordering tools or documents on every request.
  • Putting an entire document first and the user's question last.
  • Switching the same workload between models or entry points.
  • Keeping prefixes so short that they never reach a reusable granularity.

Move changing content to the end of the request and keep stable content at the beginning. That is the simplest and usually most effective fix. Caching is typically best-effort rather than a promise, so budget for partial hits instead of assuming every request will hit.

3. Estimate with the usage field

Don't guess token counts from character counts. Record the usage object after each call and watch it for a week; you will get a real picture of your workload.

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

resp = client.chat.completions.create(
    model="deepseek-chat",  # Check the pricing page for current model names
    messages=[
        {"role": "system", "content": "You are a support assistant. Answer in no more than three sentences."},
        {"role": "user", "content": "Can a shipping address be changed after an order ships?"},
    ],
    max_tokens=256,
)

usage = resp.usage
hit = getattr(usage, "prompt_cache_hit_tokens", 0) or 0
miss = getattr(usage, "prompt_cache_miss_tokens", 0) or 0

print("input", usage.prompt_tokens)
print("cache hit", hit, "cache miss", miss)
print("output", usage.completion_tokens)

If the response does not include cache breakdown fields, log total input and total output, then back the split out from your bill or usage dashboard. What matters is keeping definitions consistent; don't compare data from different dates or entry points as if it were the same measurement.

At minimum, log the timestamp, project, model, input tokens, output tokens, cache hits, retry count, and whether the call was streamed. Convert usage to money at the end of the month; watch the operational metrics daily.

4. Why identical call volume produces bills that differ severalfold

Scenario Typical token profile Where cost grows Focus
Support bot High input, short output Chat history resent every turn Summaries, caching, recent turns only
Document extraction Moderate input, structured output Same document read repeatedly Cache prefixes, batch processing
Coding assistant Large input and output Tool results and long files Retrieval, chunking, output limits
Long-form generation Short input, long output Output tokens accumulate Sectioned generation, max_tokens
Reasoning tasks Moderate input, output includes thinking Thinking tokens count as output Use non-reasoning models for simple work

The difference usually comes from five places:

  1. Different input/output ratios. Support bots and long-form writing have opposite cost structures; one average cannot describe both.
  2. Different cache hit rates. Stable prefixes can be reused, while dynamic content invalidates the cache.
  3. Different context lengths. If the whole document is sent on every turn, input cost accumulates with each turn.
  4. Different retry volumes. Resending after a 429 or a timeout adds requests; whether failed requests are billed depends on your bill.
  5. Different model tiers. Reasoning and non-reasoning models differ in both unit price and output length, and a mismatch inflates the budget.

5. Don't reverse the order of cost reduction

  1. Measure first. Use usage and logs to calculate the real token profile of every feature; don't go by feel.
  2. Then improve cache hits. Fix the system prompt, tool definitions, and knowledge prefixes, and remove dynamic content from the beginning.
  3. Then reduce input. Have RAG return only relevant passages, summarize chat history, and keep only necessary fields from tool output.
  4. Constrain output. Set a sensible max_tokens, require JSON or fixed fields, and cut repetitive explanations.
  5. Route by task. Send classification, extraction, and rewriting to lightweight models; escalate only complex reasoning.
  6. Go async and batch. Put labeling, summarization, and offline analysis that don't need a real-time response into a queue.
  7. Monitor and alert. Track usage by project, model, and scenario, and set budget ceilings.

Reverse that order and the usual outcome is this: you switch to a cheaper model, but inputs are still unmanaged and caches still miss, so the bill barely moves while quality drops.

6. Managing budgets and invoices

  • Use one key per project, and separate testing from production so they don't compete for quota.
  • Set spend limits and alerts per key so abnormal usage can be stopped automatically.
  • Reconcile weekly by project, model, and scenario to find the fastest-growing traffic.
  • Record savings from caching and model routing separately; otherwise you cannot prove the optimization worked.
  • Teams that need RMB payment and invoices can consolidate billing through a China-based AI gateway. Check the model pricing page for current rates, exchange-rate handling, and invoice terms.

Frequently asked questions

Do I need to enable caching manually?

Usually no. The service decides automatically whether a prefix can be reused; the exact mechanism and retention period are in the official documentation. Your job is to make prefixes stable, not to add more configuration.

Why does the cache hit rate fluctuate?

Common causes are timestamps, random IDs, or user information embedded in the prefix, or requests moving between models and entry points. Move variable content to the end and observe for a week.

Are reasoning tokens billed?

Thinking tokens from a reasoning model are generally counted as output; check the official documentation and your bill for the exact treatment. Don't default to a reasoning model for simple classification or extraction.

Which costs more, input or output?

For most models, output has a higher unit price than input, but cached input is usually cheaper still. Don't compare two unit prices in isolation; calculate cost per request using your own input/output ratio.

Why doesn't my estimate match the bill?

Common omissions include chat history, tool definitions, retries, cache misses, and long outputs. Match request IDs against usage logs to locate the difference.

Next steps

Start by creating a test key on ZSQH AI Gateway, run a real workload for a week, and record input, output, and cache hits. Then convert usage into a budget using the model pricing page. Model availability and prices are governed by that page.

Related reading: