What you pay for
Idle: storage only
An agent with no alarm armed costs storage and nothing else. You can leave a
hundred of them defined and pay for none of them. (
next_wake_at is not the
field that tells you so — nothing writes it, and it reads null on an agent
with an alarm too.)Awake: what it uses
Model tokens, plus any paid tool the turn called. Nothing is reserved in
advance and nothing is charged for a wake that did no work.
wakes prints rate not configured rather than being omitted.
The completion window
One knob. It never changes your model.asap is the default.
Two different things move together, and it is worth keeping them apart:
The first three columns are our executor’s schedule; the last is the
vendor’s price card, and it is the larger of the two effects.
What was measured
terminal-bench 2,long-horizon-8, GLM-5.2-FP8, n=2, 142 graded trials across
five harnesses and three windows. Everything below is a ratio; the reason is two
warnings down.
The price tariff reproduced on real agent traffic, on the card’s own input ratio:
The realized figure lands on the input ratio rather than between input and
output because this workload is 97.6–98.3% prompt tokens.
And cost per solved task falls monotonically from
asap to flex:
Six of the eight benchmark instances scored identically under all three windows.
Two moved:
compile-compcert (2/2 under asap and standard, 0/2 under flex)
and configure-git-webserver (1/2, 2/2, 1/2). Neither ran out of time — both
failed their tests — so on this grid the cheaper window is not buying its discount
by truncating the agent.
The harness comparison, and the one number that reorders it
Five harnesses, all onzai-org/GLM-5.2-FP8, all on asap, all at the same
wall-clock cap. Lead with the clean subset — the three instances
(configure-git-webserver, fix-ocaml-gc, sqlite-with-gcov) on which the cap
never bound for any arm, n=6 per arm, zero timeouts in all 30 trials. It is the
only capability-and-efficiency comparison in the run that is not partly a reading
of our own timeout:
Then the wider board — the seven instances every arm ran, two attempts each,
n=14 per arm. The grid registers eight;
hermes has no trial for train-fasttext
on any run, and that instance was solved by none of the four arms that did attempt
it, so scoring hermes out of its seven beside four arms scored out of eight credits
it with skipping the hardest task. Here the raw solve column and the conditional
one disagree, so both are printed:
min working / trial is agent execution, not trial wall clock, and the two
columns in the clean-subset table above are there to show the gap. hermes spends
13.4 minutes per trial installing itself — it builds from source on every
trial, which is also why it fragments into seven harness identities across its 14
rows (defect #59) — so its wall clock is mostly our pinning choice rather than its
latency. Agent execution is the harness doing the work, and it is the numerator of
the seconds-per-model-call column beside it.Both tables rank on TOKENS, not on dollars, and the reason is that the dollars
are not yet comparable across arms. Tokens per solved task is that arm’s total
recorded tokens divided by the tasks it solved. It is a count, so it is the same
number whichever rate card you hold it against, and it needs no correction — see
the ratios-never-dollars note below for what would have to be measured before a
cross-arm dollar column could be printed here.
cursor was evaluated and cannot enter this comparison. Its CLI talks only to
its own vendor’s infrastructure and cannot be pointed at an arbitrary model
endpoint, so there is no configuration in which it runs the pinned model the other
five hold fixed. A cursor arm would vary the model and the harness at once, so
it is excluded rather than reported.Latency between windows is now measured, and it is real. The
asap arm ran
24.7 minutes per trial and 43.8 seconds per model call; standard 50.8 min and
58.2 s/call; flex 45.1 min and 79.5 s/call. Fanning tool calls out is also a
wall-clock mechanism, and asap fans out furthest. Pick the window on price and
on how eager you want the agent to be — and if you are running against a fixed
deadline, budget the extra seconds per call rather than assuming the cheaper
window finishes in the same clock.Why batching is where the rest of the money is
An agent turn is one model call plus the tool calls it came back with. Every model call re-sends the whole transcript so far. If a run producesC total
tool output across N turns, the transcript at turn i is roughly C·i/N, so
the tokens the run reads back over its life are:
This survives prompt caching. Caching cuts the price of each re-read token.
It does not cut the number of re-reads. Batching does.
What fan-out does and does not change
Fan-out never reorders tool calls that could observe each other. Every wave runs, settles, and the next wave starts — so the transcript a fan-out plan produces is identical, entry for entry, to what strictly sequential execution produces. By construction, running calls in parallel cannot change an answer.That is a claim about the executor, not a reading of the arms. What the
benchmark says about accuracy is the flat result above — six of eight instances
identical across all three windows. It does not say that parallelism makes an
agent smarter, and neither do we.
Picking one
GLM-5.2 and nobody waiting → flex
GLM-5.2 and nobody waiting → flex
The cheapest window per solved task on the measured run (0.70 against
asap’s
1.00) with no accuracy cost that showed up at n=2. This is the one to reach for
on scheduled and batch work.GLM-5.2 and you want the middle → standard
GLM-5.2 and you want the middle → standard
Fewer, larger turns than
asap without going all the way to strictly
sequential, at 0.625 of asap’s input rate. It also scored the most solves of
any window on the measured run (13/16).Any other model, or a human is waiting → asap (the default)
Any other model, or a human is waiting → asap (the default)
asap is the only window served on models other than zai-org/GLM-5.2-FP8, so
on anything else this is not a choice. It also fans tool calls out widest and
allows speculative work, which is the configuration to hold when someone is
watching the stream.Keeping the bill bounded
Three controls, in the order they bind:1
The account balance
Runs out of credits and every primitive stops, not just agents. This is
insufficient_credits.2
The agent cap — `budget.cap_micro_usd`
Per agent, per period. A task that starts when the agent is already at or over
the cap is refused and parked at
status: "braked" with
blocked_reason: "budget" and spent: 0. This is the only budget control
measured to bind on a deployed host — and see the two warnings below for what
it does not do and what braked currently means.3
The per-task ceiling — `budget.max_task_micro_usd`
Per TASK, over its root run and every sub-agent it delegated to. The intent is a
pre-call reserve check that ends the task rather than parking it, because a
per-task ceiling never resets. 🔴 Measured against deployed staging it does not
fire at all. Do not size a deployment on it until you have proved it yourself —
see the warning below.
period: "total" is the long-horizon statement — “spend $50 on this job,
ever” — and it is the one period a project-level cap cannot express.
Watching it before it brakes
budget event on the stream — one per turn, emitted before the call
that the reserve is checked against — rather than waiting to discover the brake:
task.spent_micro_usd is the runtime’s own synchronous counter, used by the
pre-call gate. spend({ task }) reads the same meter, priced into credits —
so the two agree, and the “authoritative ledger vs advisory counter” framing
that used to sit here was wrong: an agent’s model calls write no ledger row at
all (its runtime calls the model vendor directly), which is why this endpoint
answered 0.0000 against real spend on our deployed staging host.spend() reports both records and keeps them apart: spent_credits is metered,
billed_credits is what the credit ledger holds, and each group says which
source it came from. Do not add them.