1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110# What Iris costs
**Between nothing and about 11ยข a page, and which one is a config choice.** No model is named
anywhere in Iris's code, so each deployment decides what it pays ([models.md](models.md)):
- **$0 per token.** Point the `openrouter` provider block's `base_url` at a self-hosted
open-weight model โ ollama, vLLM, llama.cpp โ and there is no model bill at all. You pay for the
machine and nothing else. Two caveats: **no round in this document measures that path**, so
nothing here says what it produces, and the agents that read page images need a model that
accepts images.
- **About 10.7ยข a page** for the suggested configuration โ Sonnet 4.6 on every agent with GPT-5.6
luna on `page`. That is the priced end of the range, and the rest of this page is where the number
comes from. One qualifier travels with it: the round that produced it ran the **previous** page
model, so the suggested setup itself has never been priced end to end, and it is a little cheaper
than the total below. A price is also not the whole decision โ [models.md ยง2](models.md) names
what the current page model costs on accessibility, which nothing in this document can show.
**10.7ยข a page.** Measured 2026-09-02 over 100 scanned pages โ round `runs-postswap-312`, total
**$10.7106**. That is the configuration deployed on that date, priced end to end. The page model
has changed once since: on 2026-09-10 the reference deployment moved `page` from Kimi K2.5 to
GPT-5.6 luna (#344), measured 15.9% cheaper on that step's own bill. So the live configuration is
a little cheaper than the table below and **has not been re-priced end to end** โ the three rows
naming `kimi-k2.5` are what this round ran. A **round** here
is one captured run of a fixed corpus through the pipeline, kept with its own logs and prices โ not
a round of the review loop, which is the other thing that word means in this repo
([README ยง Terms](../README.md#terms)).
| step | cost | share | calls | model | what it's for |
|---|---|---|---|---|---|
| `extract` | $1.4616 | 13.6% | 100 | `kimi-k2.5` | Reads the page image and writes that page's HTML. **The only step that sees the source document.** |
| `verify` | $2.5499 | 23.8% | 90 | `claude-sonnet-4-6` | Second opinion on that page: pass, or a list of problems to fix. |
| `correct` | $1.0969 | 10.2% | 63 | `kimi-k2.5` | Rewrites the page to fix what `verify` rejected. Ran on 63 of 90. |
| `recheck_sampled` | $0.0625 | 0.6% | 4 | `claude-sonnet-4-6` | Spot-checks a sample of corrections to see whether the fix held. |
| `table_join` | $1.2362 | 11.5% | 11 | `claude-sonnet-4-6` | Stitches a table split across a page break. Only runs when code cannot do the join itself. |
| `read` | $2.4034 | 22.4% | 40 | `claude-sonnet-4-6` | Reviews the assembled document and writes findings. Loops. |
| `edit` | $1.8487 | 17.3% | 4 | `claude-sonnet-4-6` | Applies those findings to the document. |
| **failed** | $0.0513 | 0.5% | 2 | `kimi-k2.5` | Two `correct` calls that errored. Billed, bought nothing. |
**Where the money goes: 59.8% ($6.4071) producing and checking pages, 39.7% ($4.2521) reviewing and
editing the finished document, 0.5% ($0.0513) wasted.** Those three blocks cover every step above and
nothing else. The eight steps sum to $10.7105 against the round's ledger total of $10.7106 โ the tenth
of a cent is the per-step cells being published to four decimals. For the same reason the share column
sums to 99.9% rather than 100%, so read it as a decomposition rounded, not as a partition.
Two things the table says that are worth saying out loud:
- **Only 13.6% of the bill is spent looking at the source document.** The other 86% is Iris checking,
repairing, reviewing and editing its own output.
- **Checking a page costs about two and a half times as much as producing it.** `verify` + `correct` +
`recheck_sampled` is **34.6%** of the bill against `extract`'s 13.6%.
Read the cost column alongside the share column, not instead of it. A step's share moves when *any
other* step's cost changes: across the last model swap `table_join`'s share rose from 8.6% to 11.5%
while its actual spend **fell 26%** ($1.6701 โ $1.2362).
## About the sample
**What it is.** Pages **1โ100 of a 166-page** 1962 [report of the US Advisory Commission on Intergovernmental
Relations](https://library.unt.edu/gpo/acir/Reports/information/M-16.pdf) โ dense hierarchical statistical tables, no charts, little running prose. Rendered at 150
dpi. The source PDF's sha256 is
`679f0a956868fa935b3bec38ebd83b3fb486e74dd87762e17248bc523c797188`, which is also its filename in the
benchmark repo's `cache/`, so any figure here can be tied to the exact bytes it came from. In the
benchmark repo as **`pages100/`**, page ids `acir-p001`โ`acir-p100`. Name the corpus when
you quote a figure from it: a second corpus there, `pages-hard57/`, uses the same `acir-pNNN` ids, and
one published figure of "54% more per call" was **18%** on the 57 pages the choice actually applied
to.
**Six things that bound every number above:**
1. **It is one document, not four.** The round reports "4 documents" because this deployment caps a
request at 25 pages (`limits.max_pages: 25`), so the PDF was submitted as four 25-page pieces.
`read` and `edit` therefore ran four times over four quarter-documents. **The cost of reviewing a
whole 100-page document has never been measured.**
2. **Pure scan, no text layer.** `text_layer: false` on all 100 pages, so every step worked from
pixels. A PDF that already carries text is a different price and is not measured here.
3. **No ground truth.** `truth_words: 0` on all 100 pages. Every quality figure Iris reports on this
corpus is a model or a script judging output, never a comparison against a known-correct
transcription.
4. **One genre.** Statistical tables. It is why some agents never fire at all on this corpus, and it
is the standing limit on every figure here.
5. **The 100 pages are the front of the report, not a sample of it.** They are pages 1โ100 of 166,
taken in order. Pages 101โ166 have never been run, so nothing here says what they cost or how
Iris handles them, and no figure above may be read as covering the whole document.
6. **Repeat runs on identical input disagree on 8 and 19 pages of 100.** The cost column is token
spend and reproduces to four decimal places. Quality figures carry that noise.
## What could change it
**#344** has already changed the page model, which moves the `extract`, `correct` and `failed` rows
by an amount only a fresh round can give: this round's own page steps summed to $2.6098, and the
15.9% that swap measured was against a different round's, so the two cannot be subtracted.
**#324** is a live proposal on the same three rows. **#329**'s copy-editor swap is measured at
โ26.1% and unapplied. The three largest levers left are not model choices at all: **#369**, **#324**'s free
artifact check, and **#365**. Each carries its own price and its own evidence; this document does not
restate them.
## Reproducing the table
```bash
node bystep.mjs runs-postswap-312 # the table above, with its own arithmetic check
node -e 'console.log(require("./pages100/index.json")[0])' # the corpus record
```
Both run in the benchmark repo (`equalify-iris-bench`), which drives this API rather than importing
Iris. Every round persists its raw model replies, so reading a paid round back costs nothing. Two
things to check before combining a figure here with a new round's: **the prompt's blob sha**, not the
commit โ two rounds ten commits apart have turned out byte-identical, and two rounds at the same
`iris_sha` have carried different `page.md` bytes โ and **the denominator**, because pages submitted,
pages that produced a file, and calls are three different counts.