Five Workers, One Clock: Why LLM Chess Runs Feel Slow
Concurrency makes one experiment accumulate several different kinds of time—and only one of them is time you actually waited
At one point in our DeepSeek chess run, two numbers seemed impossible to
reconcile. The token counter was reported as 19.277 million. The runtime was
described as roughly 117 hours. Yet the experiment had not been running for
117 hours, and five concurrent workers should have made it faster, not somehow
older than the calendar.
Nothing supernatural happened. We had compressed different units into casual language.
19.277 million tokens means approximately 19,277,000 tokens. It does not
mean 19,277 million tokens, which would be 19.277 billion. And 117 hours can
be a legitimate measure of suite-worker time even when much less than 117
hours has elapsed. If five suites run for one hour, the laboratory accumulates
five suite-worker-hours during one wall-clock hour.
That distinction sounds elementary. In a long-running agent evaluation, however, it changes how we answer almost every operational question:
- How long have we been waiting?
- How much compute-like capacity did the experiment consume?
- How much time did the model spend replying?
- Is concurrency actually saturated?
- How many games should finish by tomorrow?
- What did this model cost?
Those are six questions, not one.
This post freezes an interim snapshot of the DeepSeek V4 Flash cohort at 2026-08-05 01:28:16.619976 UTC. Four suites were still active at that cutoff, so none of the cohort-wide efficiency or cost quantities below are terminal results. The point is to make the accounting legible while the experiment is still running.
The three clocks
Our status history and game artifacts support three principal time measures.
| Clock | Frozen value | What is being accumulated? |
|---|---|---|
| Active wall time | 45.799 h | Real elapsed intervals during which at least one observed DeepSeek suite was active |
| Suite-worker time | 175.143 h | Active suites integrated over time; five simultaneous suites contribute five hours per elapsed hour |
| Reported reply time | 163.839 h | Black's accumulated per-game API reply latency, summed across games and therefore allowed to overlap |
There is also a derived normalization: 35.029 five-way-equivalent hours, which is simply 175.143 suite-worker-hours divided by the five-slot ceiling. It answers, “How long would this observed worker allocation occupy if it were packed into a perfectly full five-worker schedule?” It is not another observation of elapsed time.
The most intuitive picture is a short interval with changing concurrency:
wall-clock interval active suites worker time added
09:00–10:00 5 5 h
10:00–11:00 3 3 h
---------------------------------------------------------------
elapsed active wall time 2 h
suite-worker time 8 h
five-way-equivalent time 1.6 h
No clock is more “real” than another. They measure different resources. Wall time belongs in an answer to “How long did I wait?” Suite-worker time belongs in capacity accounting. Reply time belongs in model-service telemetry.
This resolves the earlier 117 hours dispute. If 117 represented
suite-worker-hours, then under perfect five-way saturation it would correspond
to 23.4 five-way-equivalent hours:
117 suite-worker-hours / 5 workers = 23.4 five-way-equivalent hours
It would not mean the experiment had been alive for 117 elapsed hours. Nor would it necessarily mean exactly 23.4 elapsed hours, because the real schedule may have used fewer than five workers during some intervals. To recover elapsed time, we need the concurrency history, not division by a hoped-for concurrency.
Concurrency is an integral, not a label
Saying “we ran at 5× concurrency” is too coarse. Five is a ceiling, not a guarantee that five eligible suites existed during every minute.
At the frozen snapshot, the maximum observed concurrency was five, but average concurrency while active was 3.824. Five-slot occupancy was 76.48%. The status ledger apportioned active wall time as follows:
| Concurrent suites | Active wall time |
|---|---|
| 1 | 3.938 h |
| 2 | 3.668 h |
| 3 | 9.852 h |
| 4 | 7.391 h |
| 5 | 20.950 h |
Multiplying each row's concurrency by its duration and summing yields the 175.143 suite-worker-hours. Summing the durations alone yields the 45.799 active wall-hours.
The distinction also prevents a common forecasting error. Dividing worker hours by five assumes a full queue and five continuously productive workers. Our adaptive ladders do not always provide that. A model-plus-variant may be waiting for its current ten-game block to finish before its next opponent Elo is known. Duplicate suites are prohibited. Provider failures may require supplemental games, but those are launched only after the clean-game deficit is known. Experimental correctness deliberately creates moments when the maximum safe concurrency is below the infrastructure ceiling.
At this snapshot, observed throughput was 1.114 clean games per active wall hour, or 0.291 clean games per suite-worker-hour. Another way to state the same measurement is 3.434 suite-worker-hours per clean game. If the observed concurrency mix and rate persisted, the cohort would produce about 26.73 clean games per 24 active wall-hours.
That is a conditional projection, not an ETA. Game length, opponent anchor, candidate width, provider latency, retry behavior, and the changing mix of active variants can all change after the cutoff.
Why reply-hours can exceed elapsed hours
The result JSONs report 163.839 hours of accumulated Black reply latency. That number is close to the 175.143 status-integrated suite-worker-hours, but it is more than three times the 45.799 wall-hours. This is expected under concurrent execution.
Imagine four suites awaiting four replies at once. Ten minutes later, the wall clock has advanced ten minutes, while the four games may collectively record forty reply-minutes. Summing per-game latency serializes events that were physically overlapping.
The current reply-time sum is 93.55% of suite-worker time. This is strong descriptive evidence that reply waiting occupies most of the measured worker budget. It is not, by itself, a controlled causal decomposition of total runtime. The two clocks come from different instrumentation paths and are not perfectly coextensive. The status integration excludes time before its first and after its last snapshot. Per-game reply latency does not measure every piece of harness work. A rigorous causal latency study would instrument each request attempt and every local phase with a common monotonic clock.
For the same reason, the interim variant table must not be read as proof that a smaller candidate list makes the provider faster:
| Variant | Clean games | Worker h/game | Tokens/game | Recoverable retries |
|---|---|---|---|---|
| Regular | 10 | 4.141 | 759,723 | 12 |
| Top-10 | 9 | 4.651 | 708,374 | 6 |
| Top-5 | 8 | 4.774 | 773,106 | 10 |
| Top-3 | 11 | 2.576 | 434,905 | 2 |
| Top-2 | 13 | 1.949 | 320,005 | 4 |
The rows mix opponent ratings, positions, game lengths, and incomplete ladders. They are operational summaries. A causal comparison would require the same positions, matched output limits, controlled candidate presentations, and a prespecified latency estimator.
The token number has its own unit trap
The frozen successful-game artifacts contain:
| Counter | Exact tokens | In millions |
|---|---|---|
| Prompt | 2,474,620 | 2.475 M |
| Completion | 26,626,843 | 26.627 M |
| Total | 29,101,463 | 29.101 M |
When a dashboard or report writes 19.277 M, the suffix is doing division:
19,277,000 tokens / 1,000,000 = 19.277 million tokens
Reading 19.277 as “19,277 million” applies the million multiplier twice. The
result would be one thousand times too large.
The current counters average 570,617 tokens per clean game and 7,547 tokens per ply. Completion tokens comprise 91.50% of the logged total. That distribution is consistent with an output-heavy high-reasoning chess workload, but the aggregate alone does not identify why any particular game used more tokens. Position complexity, game length, model behavior, retries, and provider accounting can be entangled.
These are also not guaranteed to be all billable tokens. They come from the successful game artifacts. A failed request attempt may incur usage and then be absent from the final game's successful-response counters. Conversely, provider caching or routing rules may change billed cost without changing the simple token sum in the way a naive calculator assumes.
Retries are overhead, not failed games
The seven indexed run-log prefixes contain 34 recoverable API-call retries,
or 0.667 per clean game and 8.82 per 1,000 plies. All 34 indexed messages share
the observed taxonomy JSON decode: Expecting value. We did not observe a
rate-limit or timeout retry in those indexed prefixes.
Yet all 51 indexed result artifacts are clean: there are zero terminal
ERROR OCCURED games.
Both statements must survive publication. “Zero errors” would erase call-level reliability overhead. “Thirty-four failed games” would falsely promote recovered attempts into terminal outcomes. The correct hierarchy is:
request attempt -> possible recoverable retry -> completed game
\-> exhausted retries -> terminal error game
Even API-call retry should not be overinterpreted as proven provider fault.
The available log classifies what the harness could not decode; it does not establish which upstream component caused every malformed or empty response.
The analysis stops retry scanning at the last GAME OVER marker represented
in the ledger. That prevents an unfinished game's changing log tail from
silently entering a denominator of completed games.
Three dollar quantities that must not be merged
Account balances and credential-level budget measurements are intentionally excluded from the public site. Per-game token telemetry is attributable; model-specific billed cost requires a request-level billing join that this cohort did not establish.
What “slow” means operationally
The experiment really is slow in the ordinary sense: 51 clean games arrived over 45.799 observed active wall-hours. But “slow” should not be explained by a single untested story.
We can establish that the configured Stockfish move budget is 0.1 seconds and that reported model reply latency occupies most measured suite-worker time. We can establish that concurrency averaged 3.824 rather than five. We can establish that 34 decode failures triggered retries. We can establish that the workload logged 29.101 million successful-game tokens, mostly completion tokens.
We cannot use these aggregate observations alone to assign a causal percentage to provider latency, reasoning length, candidate width, retry overhead, orchestrator policy, or game difficulty. They are measured correlates with different denominators. The next instrumentation revision should make the decomposition possible rather than turning proximity into causality.
That is the broader systems lesson. A concurrent evaluation does not have one runtime, one token count, or one cost. It has a ledger of clocks and scopes. The moment those scopes are collapsed, five workers can look like five times the elapsed age, 19.277 million can become 19.277 billion, and an account balance can masquerade as a model invoice.
The fix is not clever arithmetic. It is disciplined naming.
Evidence and terminal boundary
This article is bound to the
immutable Blog 14 snapshot,
which records that the source interim analysis artifact had SHA-256
2c176681cfb09fd0df23bd95408dc827c20e3932a3f080e8f7fac223461ff06b
at the declared cutoff. The live deepseek_runtime_economics_v1.json continues
to advance while suites run; it is intentionally not the publication anchor.
The human-readable methodology is in
DeepSeek V4 Flash Runtime Economics: Three Clocks, One Ledger.
Four suites were active at the cutoff. The analysis must be regenerated after the terminal DeepSeek freeze. Final cohort cost requires the request-level billing join; final efficiency and reliability require the terminal run inventory. Later values should supersede this dated snapshot, not silently rewrite it.
Operational paths, raw logs, credentials, mutable run metadata, and unpublished artifacts are intentionally excluded. Research references resolve to the versioned publication bundle rather than the host filesystem.