Skip to main content
Agents bill from the same credit balance as every other primitive. One credit is $0.05 USD. There is no subscription and no per-agent fee.

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.
The six components that appear on every spend view:
Every component prints, including the zeros, so a paid tool is never missing from this view. wakes prints rate not configured rather than being omitted.
🔴 This view used to read 0.0000 for agents with real spend, and the reason is the shape of the whole surface. Measured on staging: an agent whose own task board summed to 41,125 micro-USD across 16 tasks reported spent_credits: "0.0000" with calls: 0 on every component group. Two more agents (44,335 and 21,277 micro-USD) reported the same.The route read the credit ledger and nothing else — and an agent’s model calls never write a ledger row, because the runtime calls the model vendor directly rather than through a naive billing path. So inference is read from the runtime’s own meter, and the response carries both records side by side:billed_credits being 0.0000 next to a non-zero spent_credits is not a bug: model spend is metered but not yet invoiced. Each group says which source it came from. Never add the two totals — they are two records of one sum.If your deployment has no agents runtime, metered.available is false and only the ledger side is reported. If it has one and cannot reach it, this call fails with agent_runtime_unavailable rather than answering zero.

The completion window

One knob. It never changes your model. asap is the default.
🔴 It is served on exactly one model. standard and flex are the upstream provider’s tiers on zai-org/GLM-5.2-FP8. Every other model runs asap and nothing else, and asking for another window on one is refusedwindow_unavailable, raised at the first model call, never quietly downgraded. A window accepted and served as asap would report a discount nobody bought, with no column downstream disagreeing.
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 on zai-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:
🔴 This table used to be printed on each arm’s own denominator, and the denominator was worth a place in the ranking. Scored as they ran — hermes out of 14, everyone else out of 16 — hermes read 71% against claude-code’s 69% and came second. On the seven instances all five actually ran, claude-code is second at 79% and hermes third at 71%. Any harness table built from this data has to intersect the instance lists before it ranks anything.
🔴 The raw ranking is partly a wall-clock artifact, and a table that prints it alone is making a claim this data does not support. Conditional on not hitting the cap the ordering changes at the top: claude-code solved every trial it was given time to finish, and 4 of its 14 ran out of clock. Read both columns, or scale the cap per arm.It is not the whole mechanism, and the same table refutes the stronger version of it that used to stand here. The arms differ by 1.8x in seconds per model call (15.7 on hermes, 28.7 on bare pi), and hermes — the fastest per step of the five — still solves fewer than claude-code, which is slower per step. Step rate buys attempts; it does not buy answers.
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.
The three rows are not cap-matched, and the solve column should not be read as if they were. A slower window answers each call more slowly, so against a fixed wall-clock cap it fits fewer steps and fails for a reason that has nothing to do with price — an earlier paired run had standard hit the cap at 15.0 min on build-cython-ext while asap solved it in 10.7. To remove that artifact the sweep scaled the agent timeout with the window: asap 1x, standard 2.5x, flex 3x. That makes the COST column a fair comparison and the SOLVE column a comparison at unequal time budgets. Flat accuracy at three times the wall clock is a weaker claim than flat accuracy, and this page makes only the weaker one. The cost ratios are unaffected — they are per token, and the token counts are identical across windows for the same request.
🔴 No cross-arm dollar figure on this page, and the reason is that the card’s over-statement is a property of the ARM.The rate card books every prompt token at the full input rate. The actual bill charges tokens served from cache at a fraction of it, so the card over-states. How much it over-states depends on which API dialect the harness speaks, and therefore on whether a cached-token count comes back at all: a harness whose responses carry no cache fields books 100% of its input at full rate no matter how much of it was cached, while one that reads its usage from an endpoint reporting the cache correctly books very nearly the right number.Measured per arm, those two cases are 3.4x apart on the same model and the same benchmark — a factor of 3.4521 on one harness against 1.0172 on another. A single blended figure applied to all of them is wrong for each of them, so this page publishes none.Two consequences worth stating plainly:
  • Within one arm, across windows, the ratios are exact. The over-statement appears identically in the numerator and the denominator of a same-arm ratio and cancels. Every “this arm costs X% less at flex than at asap” figure above needs no correction and carries no caveat.
  • Across arms, dollars wait on measurement. Two of the five harnesses have a reconciled vendor reading today. The rest do not, and until they do the cross-arm columns rank on tokens per solved task, on solve rate and on wall clock — none of which depend on a price.
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 produces C 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:
That is linear in the turn count for a fixed amount of actual work. Halving the number of turns roughly halves the bill, and asking the model to do more per turn is exactly what the batch hint does. This effect is ours and applies on every model; the tariff above is the vendor’s and applies only on GLM-5.2.
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

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.
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).
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.
🔴 Set it on the AGENT. That is the only place all of it lands.
  • Agentcompletion_window is what resolveStrategy reads, so it is the only setting that moves the fan-out, the sub-agent width and the batch hint.
  • Taskwindow on sendJob/sendMessage is meant to be honoured on all three values, but only at the transport: it selects the vendor tier the call is priced at. It does not change the run’s schedule, because the manifest declares one strategy per run before turn 1. 🔴 Measured on our deployed staging host, a per-task "standard" is still replaced by the agent’s own completion_window. asap and flex store as requested on every agent; standard does not. The fix is in the runtime source and the deployed edge worker is behind it, so until your deployment’s worker is current, set the agent’s window and do not rely on a per-task "standard".
  • Schedule entrywindow is accepted by the API, stored, and echoed back on GET, and then dropped. Every schedule-fired task runs asap whatever the entry says. Do not plan a cheap 3am run this way; set the agent’s window instead.
Omitting window on a task means asap — it does not inherit the agent’s completion_window.

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.
🔴 alert_at and hard are accepted, stored and echoed, and neither changes what the runtime does.alert_at is validated as a 0–1 fraction and written to the agent’s config, and nothing in the runtime compares spend against it — there is no budget.alert emitter, and the webhook catalogue deliberately does not advertise a budget-warning event for exactly that reason. Read the budget event on the event stream instead: it carries spentMicroUsd/capMicroUsd and taskMicroUsd/maxTaskMicroUsd on every turn, before the call, which is strictly more than an 80% notification would give you.hard: false does not park the task for an approval. Both the period cap and the per-task ceiling refuse unconditionally today; the flag is not read at the gate. Treat every cap as hard, and size it accordingly.
🔴 Measured against a deployed host, max_task_micro_usd did not brake anything. An agent created with max_task_micro_usd: 1 (one micro-USD) and a period cap large enough that it could not interfere ran three consecutive tasks to status: "done", spending 17,954 / 10,359 / 12,054 micro-USD — up to 18,000x the ceiling — with error: null and blocked_reason: null on every one. Reproduced on a second agent (21,464 and 22,871 micro-USD against the same 1 micro-USD ceiling).The intended behaviour is unchanged and is what the field means: crossing it ends the task failed and non-retryable, with the spend, the reserve and the ceiling in its error. The field is required at create and it is not, today, a control you can rely on. Bound a deployment with cap_micro_usd and the account balance, and verify the per-task ceiling on your own host before trusting it.
🔴 The period cap is an ADMISSION gate, not an in-flight brake — so the first task can overshoot it without limit. Measured with cap_micro_usd: 1, period: "total", hard: true: task #1 ran to status: "done" and spent 22,534 micro-USD against a 1 micro-USD cap. Task #2 came back status: "braked", blocked_reason: "budget", spent: 0.So the park path works exactly as specified — from the second task onward. A fresh agent, or an agent whose period has just rolled over, gets one unbounded task. Size cap_micro_usd on the assumption that one task’s worth of spend can land on top of it.And a parked task does not restart on its own: the runtime’s board only ever claims tasks in queued, running or waiting, and nothing moves a task out of braked — not the period rolling over, and not raising the cap. Treat braked as terminal and re-send the work once the cap has room. Raising the cap is still worth doing: it is what lets the next task run.
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

Watch the 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.

Deleting an agent does not change history

Queued work is cancelled and the alarm chain stops. The spend ledger is kept — deleting an agent must not change what last month cost.