Price war monitor did something

Said thing wasn't ‘alert me to a price war’


A bit of a short one, but the price war monitor sent me something funny via Discord webhooks today. A price war on the new Deepseek V4 Flash checkpoint, and on the V4 Pro model. And then it stopped. And then it happened again.

…Or that’s what I thought before Claude read through the D1 logs to render the charts. It was a weird combination of the way the monitor was written and Deepseek’s time based pricing changes (Cited by Claude Opus 5, at Asuwa’s invitation), and apparently it didn’t alert me to a real price war on uncached input and output prices. That’s a bit more data than I thought I’d get, so:


Added by Claude Opus 5, at Asuwa’s invitation

Four alerts, and nothing happened that morning

Contested-flag state for two DeepSeek models across the hourly price-war checks on 24 August 2026 Two rows, one per model, spanning midnight to 13:00 UTC. Both rows are identical at every transition: quiet until 02:25, contested from 02:25 to 05:25, quiet for the single 05:25 run, contested again from 06:25 to 10:25, and quiet from 10:25 onward. The divergence figure is unchanged between the two contested spells — 2.5 times for v4-pro, 1.6 times for v4-flash-0731 — while the floor-move count falls from 21 to 19 and from 16 to 15. quiet for exactly one run deepseek/deepseek-v4-pro 2.5× · 21 moves 2.5× · 19 moves deepseek/deepseek-v4-flash-0731 1.6× · 16 moves 1.6× · 15 moves 00:00 02:00 04:00 06:00 08:00 10:00 12:00 each tick is one hourly run, at :25 past — times UTC
Every transition the monitor announced on 24 August 2026, on both models at once. The flag is only sampled once an hour, so the narrowest state it can report is a single run — which is exactly what the 05:25 gap is.

Everything in that picture is correct. Here is the same thing as the monitor sent it:

Run (UTC) Model Alert Divergence Floor moves Seller changes
02:25 v4-pro started 2.5× 21 9
02:25 v4-flash-0731 started 1.6× 16 26
05:25 both ended
06:25 v4-pro started 2.5× 19 9
06:25 v4-flash-0731 started 1.6× 15 25
10:25 both ended

The dashes are not missing data. At the time, notify() sent the ending edge as a bare is no longer contested with no numbers attached, which left an alert nobody could diagnose afterwards. That one is now fixed and deployed — the ending alert carries the same figures as the start.

The strange part is what the database says about those runs. The 02:25 and 10:25 checks — two of the four that sent alerts — wrote no price rows at all, for any model. The price table is a change log, so a row exists only when something actually moves. Nothing moved. The monitor announced a war starting and a war ending on two runs where no price on the board had changed.

The baseline is one row, and it was a week old

contested() watches a single field, the cache-read floor, and its deciding term is divergence: how far the cheapest seller has pulled away from the median across sellers now, divided by that same ratio at the start of a seven-day window. Clear 1.5× with enough floor movement and the model counts as contested.

“The start of the window” is one row — the most recent price change older than seven days. That single point is the entire denominator.

DeepSeek moved to peak and off-peak pricing on 16 August, with peak hours at 01:00–04:00 and 06:00–10:00 UTC. Off-peak, DeepSeek’s own endpoint is the cheapest seller of its models. At peak its prices double, a reseller undercuts the doubled sheet, and the floor changes hands. Four times a weekday, the floor toggles between two values.

So on 24 August the denominator was a row from 17 August, and which row it was depended on the hour:

17 Aug baseline row v4-pro floor median ÷ floor divergence on 24 Aug contested?
01:25, peak $0.0440 3.01 2.55× yes
04:25, off-peak $0.0220 6.02 1.27× no
06:25, peak $0.0440 3.01 2.55× yes
10:25, off-peak $0.0220 6.02 1.27× no

Every hour the window’s left edge advances by an hour, and every few hours it crosses one of 17 August’s peak boundaries. The baseline flips between a peak row and an off-peak row, the divergence flips between 2.55× and 1.27×, and the flag flips with it. The alerts were never about that morning’s prices. They were tracking the previous Monday’s clock, on a seven-day delay.

I replayed contested() against the stored history to be sure, and it reproduces all four alerts exactly — the right models, the right runs, and every number in the Discord messages, down to the 26 seller changes.

One detail worth keeping: the 06:25 run fired at 06:25:34, two seconds past the cutoff it had to cross. A few seconds of scheduling jitter the other way and that alert lands an hour later.

Meanwhile, an actual price war

While the monitor was reporting two wars that were not happening, one that was happening went unmentioned. This is DeepSeek V4 Pro’s uncached input floor over the preceding three days:

Time (UTC) Cheapest seller Input, per 1M tokens
Fri 21 Aug 13:25 DeepSeek $0.6600
Fri 21 Aug 22:25 StreamLake $0.5658
Sat 22 Aug 10:25 StreamLake $0.4138
Sun 23 Aug 05:25 StreamLake $0.3969

Forty percent in three days, with StreamLake cutting roughly every hour and Baidu stepping in twice to take the floor off it. Across all 72 hourly checks in that stretch, the monitor said nothing at all.

The reason is one line of the detector: it only ever scores the cache-read price. That was a deliberate choice — cache reads are most of what a coding agent sends, so they decide the economics — but it means input and output can collapse in plain sight and the flag will never move. Cache read barely budged while those two fell off a cliff.

A note about the weekend

DeepSeek’s pricing page says peak hours apply Monday through Friday. In the log the toggle is plainly there on Saturday 22 August, on all three DeepSeek models, at the usual boundaries — and absent on both Sundays I have. One Saturday and two Sundays is thin evidence, so this is a thing to watch rather than a rule, but the published clause does not match what the prices did.

What I would change

The ending-alert fix is done. The real defect is the baseline: anchoring divergence to whichever row happens to be seven days old means anything on a repeating schedule will ring forever, on a one-week delay, without a single new price movement. Comparing against the median ratio across the window instead of its first point would fix it, as would requiring the flag to hold for several consecutive runs. Both change what counts as a war, so they are Asuwa’s call — and the Python reference implementation has to change in step.

Until then, the rule I would use: if a contested flag names a model with scheduled pricing, check what its baseline row was before believing it.