titah stats
Titah has recorded per-turn usage since its first version and had no way to read
it back — 30.2M tokens were sitting in one database, unreadable. stats is that
readback:
titah stats # this folder, all time
titah stats --since 7d # the last week
titah stats --all # every project on the machine
231 turns across 74 sessions · all time · every project
by model
9router/ant 174 turns 29.7M in 241.2k out 12.34
by day
2026-08-17 72 turns 23.3M in 142.1k out 9.81
total 30,283,249 in / 296,374 out · 12.34
--since takes the same age format as sessions prune: 7d, 24h, 30d.
Prices are declared, never guessed
"provider": {
"9router": {
"models": {
"ant": { "price": { "input": 3, "output": 15, "cacheRead": 0.3 } }
}
}
}
All three figures are per 1M tokens.
Titah ships no price table and never will. Prices change, differ by region
and by contract, and a stale table produces numbers that look official and are
wrong — the same rule that keeps contextWindow undeclared rather than
estimated.
A model with no price still has its tokens counted. It is named separately
in the output rather than folded in at zero, because a model silently counted as
free is worse than one openly counted as unpriced.
!!! note “External agents are still counted separately” A delegated agent reports its own cost, and Titah never sums it with its own. They are different currencies — one is your provider bill, the other is frequently subscription quota. See Delegation.
What stops a turn
A step is a unit of conversation, not a unit of work. Twenty steps reading small files is cheap; twenty steps dispatching sub-agents is not. So the real bound is tokens:
"limits": {
"turnTokens": 400000, // input + output, summed across every step
"sessionTokens": 2000000, // across every turn in one session
"continueTurns": 5 // keep going after a limit, while the plan has open items
}
turnTokens
Defaults to 5× the model’s declared contextWindow. Titah does not know
what a model costs you, but it does know the window you declared — so the
default is derived from something real rather than guessed.
Declaring it also lifts the step ceiling from 40 to 200. Once there is a bound that measures the thing that matters, the arbitrary one steps aside.
sessionTokens
turnTokens keeps one turn from running away; this keeps a session from
creeping. The difference became real once turns could continue automatically:
six turns in a row, each obedient to its own budget, can still spend several
times over without a single limit being crossed.
It is checked before a turn starts, never mid-turn. A turn stopped halfway leaves edited files and unrun tests — worse than one turn too many.
It has no default, for the same reason as turnTokens: Titah knows the model’s
window, not what you consider a reasonable sitting.
continueTurns
This is what “keep going until it’s done” looks like, and it is a loop of bounded turns, not one unbounded turn.
A thousand-step turn is compacted over and over; by step 400 the model is working
from a summary of a summary, still going while quietly forgetting — a failure far
worse than stopping, because it is invisible. A fresh turn starts on a clean
transcript and re-reads the whole plan from the plan table, the one table
compaction never touches. So the loop does not merely dodge the forgetting
problem, it repairs it, while unbounded steps make it worse.
It fires only when the turn stopped at a limit and the plan still has
unchecked - [ ] items. The default is 0 — it spends money without asking,
and the conditions being tight is not the same as being free. Someone who turns
it on knows they are trading oversight for continuation; someone who never asked
for it must not discover it already happened.
Stops are always announced
Every limit that ends a turn says so, twice over: the model is told it is on its last step and asked to close by naming what remains, and you get a notice identifying which limit was hit and which knob raises it.
Measured, 13.2% of real turns were hitting the old 20-step wall silently — which reads, from the outside, exactly like a model that decided to stop.