How to Actually Cut Your DeepSeek API Bill
Most advice about running DeepSeek cheaply is written as if there were one input price and one output price. There aren’t. The official pricing page publishes six numbers per model: input with a context-cache hit, input without one, and output — each split again into peak and off-peak. Two of those six are fifty times apart. The gap between the bill you expect and the bill you get lives almost entirely inside that spread, and both axes of it are under your control.
All figures below were read from the official DeepSeek API pricing page on 2026-10-17, per million tokens. Vendors rename models and reprice them without much notice, so treat the structure as durable and the digits as dated.
The six prices
deepseek-flash (serving DeepSeek-V4.1-Flash):
| Per 1M tokens | Off-peak | Peak |
|---|---|---|
| Input, cache hit | $0.003 | $0.006 |
| Input, cache miss | $0.15 | $0.30 |
| Output | $0.60 | $1.20 |
deepseek-v4-pro (DeepSeek-V4-Pro-0813):
| Per 1M tokens | Off-peak | Peak |
|---|---|---|
| Input, cache hit | $0.022 | $0.044 |
| Input, cache miss | $0.66 | $1.32 |
| Output | $1.98 | $3.96 |
The Chinese-language page lists the same rates in CNY (¥1 input on a cache miss for Flash off-peak, ¥4 output, and so on), which is the primary source; the dollar table is the converted view. If you are billed in CNY, read that page instead of trusting my arithmetic.
Two ratios are worth memorising:
- Cache miss beats cache hit by 50× on Flash input ($0.15 vs $0.003), 30× on Pro.
- Pro costs 4.4× Flash on input and 3.3× on output. Not 2×. People switch models as if it were 2×.
Half the price is a matter of the clock
The official rule: peak hours are 01:00–04:00 and 06:00–10:00 UTC, Monday to Friday, excluding Chinese public holidays. Everything else is off-peak, weekends and Chinese holidays included in full. Off-peak rates are exactly half of peak rates.
Those two windows are Chinese office hours (09:00–12:00 and 14:00–18:00 Beijing time) with the lunch break cut out. That is the entire logic of the schedule, and it is very good news if your compute is not time-sensitive and you happen to live in a different timezone than Beijing.
| Peak (UTC) | Peak in Tokyo | Peak in Berlin | Peak in New York | |
|---|---|---|---|---|
| Window 1 | 01:00–04:00 | 10:00–13:00 | 02:00–05:00 | 20:00–23:00 |
| Window 2 | 06:00–10:00 | 15:00–19:00 | 07:00–11:00 | 01:00–05:00 |
Local times assume standard time (JST, CET, EST) — New York’s Window 1 starts the previous evening. The rule itself is anchored to UTC, so when the US and Europe shift for daylight saving, your expensive hours move and DeepSeek’s do not; worth re-checking in March and November.
The practical consequences:
- If you are in Japan or Korea, your working afternoon is peak. Run batch and re-index jobs after 19:00 JST, or before 09:00.
- If you are in Europe, 02:00–05:00 and 07:00–11:00 CET are expensive; the rest of the night is cheap.
- If you are in North America, both windows land at night and in the small hours — which is when most scheduled jobs already run. Check your cron timestamps against UTC, not against your wall clock.
- Saturday, Sunday and Chinese public holidays are entirely off-peak. The single cheapest thing you can do with a large corpus is re-embed it on a weekend. This costs nothing but a reschedule.
Earning the cheap input price
You only see the cache-hit rate when your prompt’s prefix matches something the service has already computed. The docs do not spell out the invalidation rules on the pricing page, so read their caching and rate-limit sections before you rely on a specific hit rate — but the engineering consequence is obvious from the price structure and holds regardless of the details: the prefix has to be stable, byte-for-byte, and it has to be first.
Things that quietly destroy your hit rate:
- A timestamp, request ID, or session UUID at the top of the system prompt. Put volatile context at the end.
- Serialising tool definitions or few-shot examples from a
map/ object whose key order is not guaranteed. Pin the order. - Editing or deleting earlier turns in a conversation. An append-only transcript keeps the prefix warm; rewriting history throws it away and re-bills the whole thing at the miss rate.
- Alternate phrasings generated per request. If a template adds a fresh sentence each call, nothing upstream of it can hit.
Worked example
An assistant call with a stable 8,000-token prefix (system prompt + tools + three examples), 500 tokens of genuinely new user content, and 700 tokens of output, at 5,000 calls/day on Flash off-peak:
HIT, MISS, OUT = 0.003, 0.15, 0.60 # Flash off-peak, USD per 1M tokens
prefix, novel, out, calls = 8_000, 500, 700, 5_000
# Nothing hits the cache: the whole 8,500-token prompt is billed at MISS
all_miss = calls * ((prefix + novel) * MISS + out * OUT) / 1_000_000 # $8.48
# Prefix hits the cache: only the 500 new tokens pay the miss rate
prefix_hit = calls * (prefix * HIT + novel * MISS + out * OUT) / 1_000_000 # $2.60
Doing it out by hand is clearer than the snippet:
| Input | Output | Per day | Per 30 days | |
|---|---|---|---|---|
| Every call a cache miss | 8,500 × $0.15 | 700 × $0.60 | $8.48 | ~$254 |
| Prefix hits the cache | 8,000 × $0.003 + 500 × $0.15 | 700 × $0.60 | $2.60 | ~$78 |
That is a 69% reduction with no change to model quality, no quantisation, no smaller model — just prompt ordering. And once the prefix is cheap, notice what the second column did to the shape of the bill: output tokens go from 25% of spend to 81% of it. The next lever is not the input side at all, it is how much the model talks.
Two follow-throughs from that:
- Cap output deliberately (
max_tokens, and “answer in three bullets” in the prompt). On Flash off-peak the output rate is 4× the cache-miss input rate and 200× the cache-hit rate, per token. - Do not pay for thinking tokens on tasks that do not need reasoning. Both models expose a non-thinking mode, and the reasoning trace counts against your output tokens — so on extraction or classification work it is pure cost. (Confirm the accounting in their thinking-mode doc before you rebuild a pipeline around it.)
Choosing the model, and the concurrency trap
deepseek-flash: 1M context, up to 384K output, image understanding supported, FIM completion
in non-thinking mode only, concurrency limit 2500.
deepseek-v4-pro: same 1M context and 384K output ceiling, no image understanding, concurrency
limit 500.
The concurrency numbers matter more than people expect. A pipeline that fans out hundreds of parallel calls against Pro is capped at 500 by the account limit regardless of how fast your workers are — while the identical pipeline on Flash has five times the headroom at a quarter of the price. If your bottleneck is throughput, “the cheaper model” may also be “the faster one”, and the token price is not even the interesting part of the decision.
A second, quieter trap is model names. deepseek-v4-flash and deepseek-v4-flash-vision-exp are
still callable, but the models behind those names are retired: requests are served by
DeepSeek-V4.1-Flash and billed at Flash rates. Nothing fails when you pin a dead alias — you just
stop knowing which model answered you, which is how a quality regression becomes a week of debugging.
Put the model ID in one configuration constant, not in twelve call sites, and rename it deliberately.
If your client already speaks Anthropic
The API has an Anthropic-format endpoint at https://api.deepseek.com/anthropic alongside the
OpenAI-format one at https://api.deepseek.com, and the docs list Responses API support for both
models. Tool calls and JSON output are supported on both. So “switching to DeepSeek” for an existing
Claude-Code or Anthropic-SDK workflow is a base-URL and API-key change, not a rewrite — which is why
the next section is worth ten minutes of your attention.
Something changes on 1 November 2026
From the pricing page, verbatim in substance: when you use the DeepSeek API through DeepSeek Harness, Claude Code, or Codex, server-side tool calls already hit the Search and Fetch APIs. Those calls are currently free, and per-request billing starts at 00:00 Beijing time on 1 November 2026. The listed rate for Search/Fetch is $0.75 per 1,000 requests.
Two weeks from the date on this article. If coding agents against DeepSeek are part of your day, today is the last cheap moment, and the useful thing to do before then is not to panic but to measure: log how many tool requests per day your setup actually fires. A heavy agentic workflow that burns 2,000 search/fetch calls a day is $1.50 a day, which is noise; 50,000 is $37.50 a day, which is a budget line. You cannot tell which one you are without counting, and after November 1 you will be paying for the answer.
The checklist
- Pin
deepseek-flashin one config constant; never hard-code a retired alias at a call site. - Stable prefix first, byte-for-byte, in a guaranteed order; volatile context last.
- Keep transcripts append-only when you can.
- Move batch, backfill and re-embedding to off-peak hours — or to the weekend, which is entirely off-peak.
- Cap output tokens; turn thinking mode off for tasks that do not reason.
- Check concurrency limits before assuming the expensive model is also the capable one.
- Log search/fetch tool calls before 2026-11-01 so you know your run-rate on day one.
- Re-read the pricing page quarterly and update the dates in anything you wrote about it.
Prices, model names, concurrency limits and the November billing change were read from the official DeepSeek API documentation on 2026-10-17: pricing and the Chinese source page for the CNY figures and per-model feature table. If anything here has gone stale, that is a bug — the numbers are the kind that move.