Re-reading store review guidelines every time they change is the kind of chore I stopped doing by hand a few months ago. As an indie developer maintaining several apps on my own, that reading is unavoidable and never the work I actually wanted to be doing. I hand the document to an agent and ask for the diff. The catch is that a 200-page PDF leaves enough of a gap before the reply arrives that I can go make tea.
Antigravity 2.11.0 (August 26) added StartPage and EndPage to view_file, along with a MediaResolution setting for image resolution. I expected the page range to be the win here. So I built a 240-page test document and measured it — and what stood out was not how much the range saved, but how quietly a low resolution loses words.
The document is one I assembled myself: A4, 240 pages, twelve chapters. It is not an actual store policy PDF, but the page count and per-page character volume are in the same range. Token counts come from the cl100k_base tokenizer. Image-side numbers are estimates, computed with the published tiling rule of 258 tokens per 768×768 tile.
First, the cost of reading the whole thing
Text extraction, with timings taken as the fastest of three runs.
| Range read | Characters | Tokens | Extraction time |
|---|---|---|---|
| All 240 pages | 904,531 | 137,528 | 0.185 s |
| Pages 141–160 (one chapter) | 75,902 | 11,514 | 0.023 s |
| Pages 141–143 (three pages) | 11,738 | 1,781 | 0.010 s |
One chapter is 8.4% of the whole document; three pages are 1.3%. Setting aside whether 137,528 tokens fits in the context window, it is simply not an amount I want to pay on every run. The page range earns its place on this table alone.
To write a page range, you first need to know the page
You can only write StartPage: 141 if you already know the chapter starts on page 141. Reading the whole file to find that out defeats the point, so I moved the lookup out of the model and onto my own machine.
# 1) Extract every page as text, preserving layout (pages are split by \f)
pdftotext -layout spec.pdf lay.txt
# 2) Pull out heading-shaped lines with their page numbers
python3 - <<'PY'
import re
pages = open("lay.txt", encoding="utf-8", errors="replace").read().split("\f")
for i, page in enumerate(pages, 1):
for line in page.splitlines():
s = line.strip()
if re.match(r"^Chapter \d+\.", s):
print(f"p{i}: {s}")
PYThose two steps took 0.20 s and produced twelve lines at 167 tokens for chapter headings alone. Including section headings, it grows to 252 lines and 2,327 tokens.
Hand the agent a 167-token index, let it pick a chapter, then pass StartPage and EndPage. Against 137,528 tokens for the full text, the entry cost rounds to nothing. The part that matters is that building the index never touches the model at all.
The heading pattern is the part you adapt. Mine matches Chapter 1. because that is how the test document is structured; a real policy PDF might use numbered clauses, an all-caps line, or a running header repeated on every page. Ten minutes spent tuning that regular expression against your own file is worth more than any prompt tweak, because the index is what the agent navigates by for every subsequent request against that document. I keep the generated index next to the PDF and regenerate it only when the file changes.
Lowering the resolution does not raise an error
This is where I stopped and looked twice.
Lowering MediaResolution obviously costs less. The question is where the floor sits. I rendered the same three pages at a range of resolutions, ran OCR on each, and compared the result against the original text. Word recall is the share of the original words that survived the round trip.
| Resolution | Image size | Word recall | Estimated tokens (3 pages) |
|---|---|---|---|
| 72 dpi | 596×842 | 65.7% | 1,548 |
| 85 dpi | 703×994 | 86.3% | 1,548 |
| 96 dpi | 794×1123 | 98.1% | 3,096 |
| 100 dpi | 827×1170 | 99.6% | 3,096 |
| 110 dpi | 910×1287 | 99.9% | 3,096 |
| 125 dpi | 1034×1462 | 100.0% | 3,096 |
At 72 dpi, a third of the words are gone. The run still completes. No error, no warning. What comes back is not a refusal to read — it is a summary assembled from a partial reading.
That is the awkward part: the output does not look broken. It reads as coherent prose, so nothing in the text points at the clause that went missing. For a document where the expensive mistake is the requirement you failed to notice, this is the worst available failure mode.
The moments when you most want to save money are exactly the moments to measure the floor first. And notice that 72 dpi and 85 dpi carry the identical estimated cost of 1,548 tokens. There is a band where you give up accuracy and get nothing back for it.
Raising it has a ceiling too
Same three pages, pushed the other direction.
| Resolution | Image size | Word recall | Estimated tokens (3 pages) | Render time |
|---|---|---|---|---|
| 110 dpi | 910×1287 | 99.9% | 3,096 | 0.80 s |
| 150 dpi | 1241×1754 | 100.0% | 4,644 | 1.36 s |
| 300 dpi | 2481×3508 | 99.8% | 15,480 | 2.68 s |
At 300 dpi you spend 5.0× the tokens of 110 dpi and recall does not improve. With tile-based counting that is expected: doubling the resolution multiplies tiles on both axes, so cost tracks area. The usable information, once the glyphs are legible, stops growing.
For a PDF with an extractable text layer, those same three pages cost 1,781 tokens as text. Reading them as 300 dpi images costs 8.7× that. Unless the document is a scan or the figures are the content, there was never a reason to send images at all — which is an obvious conclusion I arrived at only after measuring.
The jump between 125 dpi and 150 dpi is worth understanding, because it is not gradual. Cost is flat from 96 dpi through 125 dpi — every one of those renders lands inside the same tile grid, so they all bill at 3,096 tokens. Cross the grid boundary and an extra row of tiles appears, and the price steps up at once. That means the cheapest useful setting is the highest resolution that still fits the current tile count, not the lowest one you can tolerate. Picking 96 dpi over 125 dpi buys you nothing and costs you three percentage points of recall.
The same shape of waste shows up across attachment formats, not just PDFs. I ran the equivalent measurement on tabular data in the day I found out the date column was the expensive part of my sales CSV.
The order I follow now
I turned the measurements straight into a sequence.
- Check whether the PDF has an extractable text layer at all (if
pdftotextreturns nothing, treat it as a scan). - If text comes out, do not rasterize. Build the index locally and pass
StartPageandEndPageper chapter. - When images are unavoidable, start at the equivalent of 100–125 dpi. Past that you are buying tiles, not information.
- Before going lower, verify recall on a few pages rather than applying it document-wide.
Step 3 is the one most likely to shift on you, and I would rather say that plainly than hand you a number that fails quietly. Documents set in small type, or in thin CJK faces, should push the floor upward, and I intend to re-measure against my own Japanese documents rather than assume this transfers. Take the numbers here as a method to copy, not a setting to paste.
StartPage is the option you will reach for first, and it does help. But resolution was the setting actually driving both cost and accuracy. Next time you hand a long PDF to an agent, render three pages at two different resolutions and compare what comes back. Ten minutes gets you the floor for your own documents.
Thank you for reading this far. If the method saves someone a little waiting, that is enough.