diff --git a/AGENTS.md b/AGENTS.md index ff4db72..9dc6bac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -105,10 +105,11 @@ deepseek usage --entries --json # individual calls deepseek pricing --json # the schedule and the billing period right now ``` -Pricing is time-of-day from 2026-08-16 16:00 UTC: peak hours 01:00–04:00 -and 06:00–10:00 UTC bill at twice the off-peak rate. `pricing` computes -the current period locally — no network, nothing spent — from the same -schedule the cost estimates use. +Pricing has been time-of-day since 2026-08-16 16:00 UTC: peak hours +01:00–04:00 and 06:00–10:00 UTC bill at twice the off-peak rate. Never +quote a DeepSeek price without saying which period it is — `pricing` +computes the current one locally, no network, nothing spent, from the +same schedule the cost estimates use. ### Documentation, offline @@ -264,9 +265,11 @@ Every call prints a usage line to stderr and appends to for a quiet run. - Costs are estimates from the published USD rate card, not billed amounts. Token counts are exact. -- Cached input tokens cost 50× less than uncached ones. Put the stable - part of a prompt first — the same system prompt and files across calls - — and `deepseek usage` will show the saving. +- Cached input tokens cost about 30× less than uncached ones. Put the + stable part of a prompt first — the same system prompt and files across + calls — and `deepseek usage` will show the saving. Prompt structure is + still the biggest lever on a bill; the hour of the day comes second, + and it is worth at most 2×. ## Cautions diff --git a/Makefile b/Makefile index 5e5137a..98a7e9d 100644 --- a/Makefile +++ b/Makefile @@ -32,19 +32,25 @@ cover-gate: # page by page and extracts the FAQ out of its JS bundle. A sibling # checkout is used when there is one — that is the loop while working on # both — and otherwise it is fetched, so CI and a bare clone both work. +# +# The mirror also tracks dsh, DeepSeek's agent harness, in en/dsh — 112 +# pages of a different product. This binary carries the API reference, so +# that subtree is excluded: it would quadruple the payload and it out-ranks +# the API pages on shared words like "tool" and "session". CORPUS=internal/docs/corpus.tar.gz +CORPUS_EXCLUDE=--exclude=en/dsh DOCS_REPO=https://github.com/thevibeworks/deepseek-docs .PHONY: corpus corpus: @if [ -d ../deepseek-docs/content/en ]; then \ echo "packing from ../deepseek-docs"; \ - tar -C ../deepseek-docs/content -czf $(CORPUS) en; \ + tar -C ../deepseek-docs/content $(CORPUS_EXCLUDE) -czf $(CORPUS) en; \ else \ echo "fetching from $(DOCS_REPO)"; \ tmp=$$(mktemp -d); \ curl -sSL $(DOCS_REPO)/archive/refs/heads/main.tar.gz | tar -xz -C $$tmp --strip-components=1; \ - tar -C $$tmp/content -czf $(CORPUS) en; \ + tar -C $$tmp/content $(CORPUS_EXCLUDE) -czf $(CORPUS) en; \ rm -rf $$tmp; \ fi @echo "$(CORPUS): $$(du -h $(CORPUS) | cut -f1), $$(tar tzf $(CORPUS) | grep -c '\.md$$') pages" diff --git a/README.md b/README.md index c113392..d11bbc3 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,11 @@ It also does three things `curl` will not: on every later request. `--continue` handles that; without tools it strips the same field, because replaying it there just burns tokens. - **Prices every call.** DeepSeek's disk KV-cache makes a cached input - token **50× cheaper** than an uncached one. That split is invisible - unless something reads `prompt_cache_hit_tokens` and does the - arithmetic. This does, on every call, and keeps a local ledger. + token **~30× cheaper** than an uncached one, and since 2026-08-16 the + hour of the day doubles the bill on top. Both splits are invisible + unless something reads `prompt_cache_hit_tokens`, knows the schedule + and does the arithmetic. This does, on every call, and keeps a local + ledger. - **Carries the manual.** `deepseek docs ask "..."` answers questions about the DeepSeek API from DeepSeek's own documentation, offline, with a citation per claim. The tool that talks to an API should be able to @@ -374,9 +376,10 @@ context cache saved ~$0.23 (1.7M of 2.2M prompt tokens replayed) costs are estimates from the published USD rate card, not billed amounts ``` -That last line is the point. Cached input costs $0.0028/M against -$0.14/M for a miss — structuring prompts so the stable part comes first -is worth real money, and this is how you see whether it worked. +That last line is the point. Cached input costs $0.007/M against +$0.22/M for a miss in an off-peak hour — structuring prompts so the +stable part comes first is worth real money, and this is how you see +whether it worked. Honest limits: diff --git a/gateway/DESIGN.md b/gateway/DESIGN.md index bd8b429..ef9f854 100644 --- a/gateway/DESIGN.md +++ b/gateway/DESIGN.md @@ -280,20 +280,29 @@ scarce operation and gets the conservative boundary. ## Limits, and why these numbers -Worst-case cost per anonymous user per day, at flash rates -($0.14/M input, $0.28/M output): +Worst-case cost per anonymous user per day, at flash off-peak rates +($0.22/M input, $0.66/M output): ``` -60,000 input × $0.14/M = $0.0084 -20,000 output × $0.28/M = $0.0056 +60,000 input × $0.22/M = $0.0132 +20,000 output × $0.66/M = $0.0132 ------- - $0.014 / user / day at full burn + $0.0264 / user / day at full burn, off-peak + $0.0528 / user / day at full burn, peak ``` -So a $1/day budget serves ~70 users burning *everything*, or several -hundred normal ones — a normal turn is a few hundred input and a few -hundred output tokens, about $0.0003. Roughly **3,300 ordinary turns per -dollar.** +So a $1/day budget serves ~38 users burning *everything* off-peak, ~19 at +peak, or several hundred normal ones — a normal turn is a few hundred +input and a few hundred output tokens, about $0.0006. Roughly **1,700 +ordinary turns per dollar off-peak, 850 at peak.** + +These are the numbers of the card that took effect 2026-08-16 16:00 UTC, +and they roughly halved the free tier's reach at an unchanged budget: the +old flat card ($0.14/$0.28) made the same worst case $0.014/user/day. The +quotas below have not been retuned for it — the budget breaker is what +actually bounds spend, and it does its job at any card — but the reach +per dollar is now a time-of-day figure, and the peak windows are the +expensive seven hours. | setting | default | why | |---|---|---| diff --git a/gateway/internal/meter/meter_test.go b/gateway/internal/meter/meter_test.go index 77cfb1a..7013667 100644 --- a/gateway/internal/meter/meter_test.go +++ b/gateway/internal/meter/meter_test.go @@ -7,6 +7,12 @@ import ( "time" ) +// A fixed instant outside every peak window, for the tests that are about +// token attribution rather than about the schedule. Pricing them at +// time.Now() made them fail the moment the repricing landed, which told +// us nothing about the code under test. +var offPeakInstant = time.Date(2026, 8, 17, 12, 0, 0, 0, time.UTC) + // The payloads below are verbatim from the live API on 2026-08-05, one // per wire format, captured with `deepseek raw`. Hand-written fixtures // would only prove this package agrees with my memory of the shapes; @@ -69,9 +75,10 @@ func TestAnthropicCacheReadsAreAddedToInput(t *testing.T) { t.Errorf("cache hits = %d, want 900", u.CacheHitTokens) } // And the price must reflect that only 130 tokens were billed at the - // full rate. - want := 900*0.0028/1e6 + 130*0.14/1e6 + 7*0.28/1e6 - if got := Cost("deepseek-v4-flash", u); math.Abs(got-want) > 1e-12 { + // full rate. Priced at a fixed off-peak instant: what is under test is + // which tokens land on which rate, not which card is in force today. + want := 900*0.007/1e6 + 130*0.22/1e6 + 7*0.66/1e6 + if got := CostAt("deepseek-v4-flash", u, offPeakInstant); math.Abs(got-want) > 1e-12 { t.Errorf("cost = %v, want %v", got, want) } } @@ -82,8 +89,8 @@ func TestOpenAICacheHitsAreInsideInput(t *testing.T) { if u.InputTokens != 1000 || u.CacheHitTokens != 960 { t.Fatalf("in %d hit %d, want 1000/960", u.InputTokens, u.CacheHitTokens) } - want := 960*0.0028/1e6 + 40*0.14/1e6 + 10*0.28/1e6 - if got := Cost("deepseek-v4-flash", u); math.Abs(got-want) > 1e-12 { + want := 960*0.007/1e6 + 40*0.22/1e6 + 10*0.66/1e6 + if got := CostAt("deepseek-v4-flash", u, offPeakInstant); math.Abs(got-want) > 1e-12 { t.Errorf("cost = %v, want %v", got, want) } } diff --git a/internal/cli/e2e_test.go b/internal/cli/e2e_test.go index a1c5823..3dee18a 100644 --- a/internal/cli/e2e_test.go +++ b/internal/cli/e2e_test.go @@ -412,7 +412,11 @@ func TestModelsJoinsThePublishedRateCard(t *testing.T) { if !strings.Contains(got.stdout, "deepseek-v4-flash") { t.Errorf("stdout = %q", got.stdout) } - if !strings.Contains(got.stdout, "0.14") { + // Which figure depends on the hour: flash cache-miss input is $0.22 + // off-peak and $0.44 peak. Both are published numbers, so asserting + // on either keeps this a real check without making it a time bomb + // that fails whenever the suite runs inside a peak window. + if !strings.Contains(got.stdout, "0.22") && !strings.Contains(got.stdout, "0.44") { t.Errorf("the price should sit next to the model, got %q", got.stdout) } } diff --git a/internal/deepseek/pricing.go b/internal/deepseek/pricing.go index 42057c3..c162ed0 100644 --- a/internal/deepseek/pricing.go +++ b/internal/deepseek/pricing.go @@ -37,11 +37,16 @@ type Price struct { Output float64 } -// RepriceAt is when DeepSeek's dated repricing takes effect: 16:00 UTC -// on 2026-08-16 (midnight, Beijing), announced 2026-08-13 with the V4 GA +// RepriceAt is when DeepSeek's repricing took effect: 16:00 UTC on +// 2026-08-16 (midnight, Beijing), announced 2026-08-13 with the V4 GA // release. From that instant the API bills peak/off-peak on a new, // higher card, with off-peak at half the peak rate. // +// This is live, and measured, not just read off the page: a 188,542 +// cache-miss-token call to pro in the off-peak window on 2026-08-17 +// settled at 0.84 CNY, i.e. 4.46 CNY/1M against the new card's 4.5 and +// the old card's 3.0. +// // TASTE.md's rule against applying announced-but-undated numbers does // not apply here — these numbers carry their date, so the switch is // encoded and gated on it, exactly as that scar's expiry clause says. @@ -49,6 +54,10 @@ type Price struct { var RepriceAt = time.Date(2026, time.August, 16, 16, 0, 0, 0, time.UTC) // pricesFlat is the card published 2026-08-02, in force before RepriceAt. +// That instant has passed, so nothing live prices against it any more; it +// stays because the ledger stores token counts rather than dollars, and a +// call made before the flip must still reprice under the card it was +// actually billed at. var pricesFlat = map[string]Price{ ModelFlash: {CacheHitInput: 0.0028, CacheMissInput: 0.14, Output: 0.28}, ModelPro: {CacheHitInput: 0.003625, CacheMissInput: 0.435, Output: 0.87}, diff --git a/internal/docs/corpus.tar.gz b/internal/docs/corpus.tar.gz index f205e73..b6560f2 100644 Binary files a/internal/docs/corpus.tar.gz and b/internal/docs/corpus.tar.gz differ diff --git a/site/bench/index.html b/site/bench/index.html index 05a4d70..64cf120 100644 --- a/site/bench/index.html +++ b/site/bench/index.html @@ -30,7 +30,7 @@ """, @@ -1423,7 +1462,7 @@ def jstr(s): ("What did the V4-Pro GA (0813) checkpoint change over the preview?", "The model ID and the rate card did not change; the checkpoint did. Against the April V4-Pro preview, DeepSeek's chart shows large agentic gains: DeepSWE 12.8 to 62.7, DSBench-Hard 31.1 to 67.2, CyberGym 52.7 to 83.3, Terminal-Bench 2.1 72.1 to 87.9, Toolathlon 55.9 to 74.1. Jumps that size point to agent post-training and better tool-error handling rather than a new base model, and none of them are independently verified yet."), ("What is the DeepSeek kill line (斩杀线)?", - "The kill line is a community idea that DeepSeek's price-to-capability ratio sets a threshold that removes the reason to exist for any model that is both weaker and more expensive. V4-Pro is roughly 11x cheaper than GPT-5.6 Sol on cache-miss input and 34x cheaper on output, and about 138x cheaper on cache-hit input. It does not kill the frontier: the strongest closed models still finish the hardest tasks in fewer turns. It kills the middle, where a model costs more and does less."), + "The kill line is a community idea that DeepSeek's price-to-capability ratio sets a threshold that removes the reason to exist for any model that is both weaker and more expensive. On the card in force since 2026-08-16, V4-Pro is 7.6x cheaper than GPT-5.6 Sol on cache-miss input off-peak (3.8x at peak), 15x cheaper on output (7.6x peak) and 23x cheaper on cache-hit input (11x peak). The repricing narrowed all three: on the flat card that ran until then the figures were 11.5x, 34.5x and 138x. It does not kill the frontier: the strongest closed models still finish the hardest tasks in fewer turns. It kills the middle, where a model costs more and does less."), ("Is DeepSeek-V4-Pro better than Claude or GPT for coding agents?", "Per attempt, the strongest closed models remain more reliable on the hardest multi-step tasks and usually need less steering. Per dollar, V4-Pro changes the arithmetic: its cheap cached input makes repeated review, parallel workers and long tool loops affordable in a way per-token-stronger models are not. The practical answer is to route by role, run an internal bake-off, and measure successful-task cost, not per-token price."), ]), @@ -1530,20 +1569,27 @@ def jstr(s):
| Per 1M tokens | v4-flash | v4-pro | GPT-5.6 Sol | pro is cheaper by |
|---|---|---|---|---|
| input, cache miss | $0.14 | $0.435 | $5.00 | ~11.5x |
| input, cache hit | $0.0028 | $0.003625 | $0.50 | ~138x |
| output | $0.28 | $0.87 | $30.00 | ~34.5x |
| input, cache miss | $0.22 / $0.44 | $0.66 / $1.32 | $5.00 | 7.6x / 3.8x |
| input, cache hit | $0.007 / $0.014 | $0.022 / $0.044 | $0.50 | 23x / 11x |
| output | $0.66 / $1.32 | $1.98 / $3.96 | $30.00 | 15x / 7.6x |
DeepSeek prices are the published USD rate card of -2026-08-02, unchanged at GA; they are a conversion of the RMB card -(¥3 / ¥0.025 / ¥6 per 1M for pro) at one consistent rate. GPT-5.6 -Sol prices are from OpenAI's own listing. From 2026-08-16 16:00 UTC DeepSeek -bills peak/off-peak on a higher card – the -pricing page has the dated schedule. Even at -the new peak rate, pro stays ~3.8x cheaper than GPT-5.6 Sol on cache-miss -input and ~7.6x on output.
+DeepSeek cells read off-peak / peak, on the +card in force since 2026-08-16 16:00 UTC; they are a conversion of the RMB +card (pro: ¥4.5 / ¥0.15 / ¥13.5 per 1M off-peak, double at peak) +at one consistent rate. GPT-5.6 Sol prices are from OpenAI's own listing. +The pricing page has the full schedule.
+These ratios were 11.5x / 138x / 34.5x on the flat card +that ran until 2026-08-16. The cache-hit column is where the argument +lived – a 138x edge is what made replayed context, parallel reviewers +and long tool loops nearly free – and it is now 23x off-peak, 11x at +peak. That is still a large advantage. It is no longer a different +category, and any plan that was built on the old number should be +re-costed rather than assumed.
+The sober version matters as much as the slogan. The kill line is real for
the middle of the market: a model that costs more than V4-Pro and
scores below it on the table above is hard to justify, and that is most of the
@@ -1564,11 +1610,16 @@ def jstr(s):
ds chat -m deepseek-v4-pro and the
Anthropic remap make the switch one flag.
ds usage reports what the cache saved so you
-can see whether it is working. This is where the 138x cache-hit number turns
-from a table cell into a bill.ds pricing says which period you are in.ds docs changelog.
-It landed on schedule. At 16:00 UTC on 2026-08-16 – +midnight in Beijing – DeepSeek's peak/off-peak card took effect, and +the Models & Pricing page no +longer carries the flat card at all: the old figures are deleted, and the +footnote that used to say the new prices “take effect at 16:00 UTC on +August 16” now simply describes how billing works. Both the English +and Chinese editions read the same way.
+ +| Per 1M tokens | v4-flash | v4-pro |
|---|---|---|
| input, cache hit | $0.007 / $0.014 | $0.022 / $0.044 |
| input, cache miss | $0.22 / $0.44 | $0.66 / $1.32 |
| output | $0.66 / $1.32 | $1.98 / $3.96 |
Cells read off-peak / peak. Peak hours are +01:00–04:00 and 06:00–10:00 UTC daily – 09:00–12:00 +and 14:00–18:00 Beijing, seven hours a day – and every other hour +is off-peak at half the peak rate. In RMB, pro is +¥0.15 / ¥4.5 / ¥13.5 off-peak and ¥0.3 / ¥9 / ¥27 at +peak.
+Against the flat card of 2026-08-02, off-peak / peak: +pro is 6x / 12x on cached input, 1.5x / 3x on cache-miss +input and 2.3x / 4.6x on output. Flash is 2.5x / 5x, 1.6x / 3.1x and +2.4x / 4.7x.
+ +The headline “up to 3x” is the cache-miss number, and it is the +least interesting one. The steep rise is on pro's cached input: 12x +at peak, 6x off-peak. That is the token DeepSeek was famous for +pricing at almost nothing, and it is the token an agent sends most of – +every replayed system prompt, every re-sent file, every turn of a long tool +loop. A pro workload built on a 99%-cache-hit prefix does not see a 3x bill; +it sees something much closer to 12x. The cheapest thing on the menu went up +the most.
+Note that this one is pro-specific. Flash's cached input rose 2.5x +off-peak and 5x at peak, so the two models' cache rates have converged: +pro's cached token used to cost 1.3x flash's and now costs 3.1x it. If you +were on pro mainly because replayed context was almost free there, that +particular reason just got much weaker.
+The cache is still the biggest lever, just a shorter one: a cached input +token now costs about 1/30th of a miss, where it was 1/50th +on flash and 1/120th on pro. Structuring a prompt so the stable part comes +first is worth up to 30x; moving the same work off-peak is worth 2x. Do both, +in that order.
+ +A docs page can update before a billing system does, so this is measured.
+On 2026-08-17, in an off-peak window, one deepseek-v4-pro call
+with 188,542 cache-miss input tokens settled against a real
+RMB account at 0.84 CNY – that is 4.46 CNY per 1M
+against the published off-peak 4.5, where the old flat card would have made
+it 3.0. Settlement lags the call by a minute or two and arrives in steps, so
+poll the balance rather than reading it once.
One more detail for anyone reconciling the two cards: the USD +figures are the RMB ones converted at a single rate of 6.818 +(it was 6.897 before), with flash's cache-hit cell rounded down – +¥0.05 at 6.818 is $0.00733, published as $0.007.
+ +The switch was encoded when it was announced and
+gated on its instant, so estimates started using the new card by themselves.
+ds pricing names the period you are in right now and when it
+next changes; ds models prints the rate in force beside the
+model list; the ledger keeps token counts
+rather than dollars, so calls made either side of the flip reprice under the
+card that was actually real. The embedded docs corpus has been refreshed, so
+ds docs show quick_start/pricing is the new page offline.
The one habit worth adopting: stop quoting a DeepSeek price +without naming the period. There is no longer a single number to +quote, and the difference is a factor of two.
+ +The other shoe drops. Alongside the V4-Pro GA release, DeepSeek's
Models & Pricing page now
carries the repricing that the August 6 notice
@@ -1745,9 +1872,16 @@ def jstr(s):
enough that you should never change history … even more so with deepseek
because their cache hit pricing is so low
(no stripping old thinking tokens,
no rewriting tool results to save context)
-(p1necone). The 138x
+(p1necone). The
cache-hit lever on the cost page is only real if the
prefix actually stays put.
Read this with the date in mind. These +reports were written against the flat card, when pro's cache-read price was +138x below GPT-5.6 Sol's. The 2026-08-16 +repricing raised exactly that number – 6x off-peak, 12x at peak +– leaving the edge at 23x/11x. The advice holds: keep the prefix +stable, never rewrite history. The cost simulations that concluded pro comes +out cheaper do not automatically hold, and are worth re-running.
On GLM-5.2, one report from OpenCode work on an old Unix-clone codebase: diff --git a/site/cost/index.html b/site/cost/index.html index 6ee7095..3e76dee 100644 --- a/site/cost/index.html +++ b/site/cost/index.html @@ -87,20 +87,23 @@
DeepSeek's headline feature is a disk-backed context cache that -makes a repeated prompt prefix roughly fifty times cheaper. That saving is -invisible unless something is counting – so this counts.
+makes a repeated prompt prefix roughly thirty times cheaper. Since +2026-08-16 a second lever sits on top of it: the hour of the day, worth 2×. +Neither is visible unless something is counting – so this counts.USD per 1M tokens, as published on 2026-08-02 and in force before -2026-08-16 16:00 UTC – from that instant DeepSeek bills peak/off-peak -on a new card, and the pricing page carries -the dated schedule:
+USD per 1M tokens. Peak hours are 01:00–04:00 and 06:00–10:00 +UTC daily; every other hour is off-peak at half the peak rate. The +pricing page carries the full schedule and +names the period you are in right now:
| Model | Input (cached) | Input (miss) | Output | |
|---|---|---|---|---|
| Model | Period | Input (cached) | Input (miss) | Output |
deepseek-v4-flash | $0.0028 | $0.14 | $0.28 | |
deepseek-v4-pro | $0.003625 | $0.435 | $0.87 | |
deepseek-v4-flash | off-peak | $0.007 | $0.22 | $0.66 |
| peak | $0.014 | $0.44 | $1.32 | |
deepseek-v4-pro | off-peak | $0.022 | $0.66 | $1.98 |
| peak | $0.044 | $1.32 | $3.96 |
On flash, a cache hit costs 1/50th of a miss. The same -3,200-token prompt, sent twice:
+On flash, a cache hit costs 1/31st of a miss per token. +The same 2,900-token prompt, sent twice:
$ ds chat "..." --system @prefix.txt
one
-· flash · 3.2k in · 1 out · ~$0.000450 · 0.84s
+· flash · 2.9k in · 1 out · ~$0.000642 · 580ms
$ ds chat "..." --system @prefix.txt
two
-· flash · 3.2k in (100% cached) · 1 out · ~$0.000011 · 1.04s
+· flash · 2.9k in (97% cached) · 1 out · ~$0.000043 · 630ms
+A 15× drop on the whole call, for changing nothing but sending the +same prefix again. It is 15× and not 31× because the 3% that +changed – the tail of the prompt, and the question itself – +still bills at the miss rate: the realised saving is always the rate ratio +times how much of the prompt you kept identical. Hence the practical rule: +put the stable part of a prompt first – same system +prompt, same files, in the same order – and let the variable part come +last.
+ds tokens counts by sending the text to the FIM endpoint, so
+it warms the cache: measure the cache with two chat calls, or
+the first one is already a hit.
A 40× drop, for changing nothing but sending the same prefix again. -The practical rule: put the stable part of a prompt first -– same system prompt, same files, in the same order – and let the -variable part come last.
Thinking mode is on by default and adds a fixed template to your input @@ -204,18 +217,16 @@
ds balance shows which.ds pricing
-carry the schedule and the new numbers.