How Many Tokens Is a PDF? 4 Vendors, 4 Rules, 15 to 2,100 a Page
Contents
- How do you send a document to a model?
- How do you tell whether a model really read the file?
- How does each vendor count a PDF sent as a file?
- When does extracted text fail?
- How do you pay less for documents?
- What do you do with a Word file?
- How we measured
- FAQ
- How many tokens is a PDF page?
- Is it cheaper to send a PDF or its extracted text?
- Can an LLM read a scanned PDF?
- Which models accept PDF files directly?
- How do I reduce the cost of a long PDF?
- Related reading
A PDF sent to a model as a file is billed by a different rule at each vendor. GPT-6 counts the tokens of the page’s text and about 15 more per page. Claude counts the text and adds 1,558 tokens for every page. Gemini counts 515 tokens per page and nothing for the text. Qwen 3.8 adds 2,098 per page to the text. We measured the rules by sending the same pages with more and more text on them, then sent ten documents to fifteen models to find the cheapest way of sending each kind that still gets the answers right.
TL;DR
- Per PDF page sent as a file, GPT-6 adds 15 tokens to the text, Claude 1,558 and Qwen 3.8 2,098. Gemini bills a flat 515, text free.
- Extracted text answered 0 of 150 chart questions and 0 of 105 questions on a scanned document.
- Routing pages one by one cut a mixed document from 17,228 tokens to 6,543 on Claude Sonnet 5.5, all 12 answers right.
- Sending 4 selected pages of a 120-page PDF cut Claude Sonnet 5.5’s input from 253,822 tokens to 8,758.
How do you send a document to a model?
In one of three ways: as a file, as images of its pages, or as text you extract first.
import base64
import pymupdf # pip install pymupdf
doc = pymupdf.open("report.pdf")
b64 = lambda data: base64.b64encode(data).decode() # binary written as text, so it fits in JSON
# 1. As a file. The vendor decides how to read it.
as_file = [{"type": "file", "file": {"filename": "report.pdf", # OpenAI-compatible chat
"file_data": "data:application/pdf;base64," + b64(open("report.pdf", "rb").read())}}]
as_document = [{"type": "document", "source": {"type": "base64", # Anthropic Messages API
"media_type": "application/pdf", "data": b64(open("report.pdf", "rb").read())}}]
# 2. As page images. You render each page; any model that accepts images takes these.
as_images = [{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64," +
b64(page.get_pixmap(dpi=72).tobytes("jpeg"))}} for page in doc]
# 3. As text. The text layer is the selectable text stored in a PDF. A scan has none.
as_text = "\n\n".join(page.get_text() for page in doc)
What each of the fifteen models accepted on the chat endpoint:
| Model | PDF as a file | Page images | Text |
|---|---|---|---|
| GPT-6.1 Sol, GPT-6 Luna | yes | yes, up to 50 per request | yes |
| Claude Opus 5.5, Sonnet 5.5, Haiku 5.5 | yes | yes | yes |
| Gemini 3.1 Pro, Gemini 3.8 Flash | yes | yes | yes |
| Qwen 3.8 Max, Qwen 3.8 Flash | yes | yes | yes |
| Qwen 3.6 35B (open weights), DeepSeek V4.1 Flash, GLM 5.3 Flash, Kimi K3 | no | yes | yes |
| GLM 5.3, DeepSeek V4 Pro | no | no | yes |
Page images are the one route every vision model takes, including the four open-weight models, whose weights are published and which reject a file. On the endpoint we used, the Gemini models took the PDF as a data URL in an image part; Google’s own API takes it as inline data.
How do you tell whether a model really read the file?
Ask for something only the file contains, and look at the input token count. An unsupported input sometimes returns a 400 error and sometimes is dropped while the model answers anyway. In our probe the two models without vision ignored an image part and replied with 27 and 98 input tokens for a two-page document, and one model that was sent a URL in place of the file answered with invented content.
r = client.chat.completions.create(model=model, messages=[{"role": "user", "content": as_file + [question]}])
read_it = "MF-OPS-2291" in r.choices[0].message.content # a string found only in the document
plausible = r.usage.prompt_tokens > 200 * len(doc) # a dropped file leaves a few dozen tokens
Knowing what kind of page you have needs no model, and the routing further down depends on it:
def kind(page) -> str:
if len(page.get_text().strip()) < 40:
return "scan" # no text layer: needs OCR or an image
if page.get_images() or len(page.get_drawings()) > 60:
return "visual" # a picture or a chart drawn on the page
return "text"
How does each vendor count a PDF sent as a file?
By four different rules. We built a six-page PDF with 0, 80, 250, 500 and about 670 words on each page, and again with a chart on every page, and sent each as a file and as extracted text.
| Vendor | Tokens for a PDF sent as a file |
|---|---|
| GPT-6 | The text tokens plus 14.5 a page. A page with a picture on it adds about 650 to 1,700 |
| Claude | The text tokens plus 1,558 a page, exactly. A chart on the page adds nothing |
| Gemini | 515 a page, whatever is on it. The text is not counted |
| Qwen 3.8 | About 0.94 of the text tokens plus 2,098 a page. A chart adds about 770 |
A token is the unit a model is billed in, roughly three quarters of an English word. Models of one family counted alike to within a few tokens.
Two of the rules differ from what the vendors publish, at least on the route we measured. Google’s documentation says a page is 258 tokens and the PDF’s own text is not charged; we measured 515 a page, with the text free as stated. OpenAI’s says a PDF reaches the model as extracted text and page images; a page of plain text carried no image cost here. Anthropic’s says each page is processed as text and as an image, typically 1,500 to 3,000 tokens, which matches.
What follows from the rules:
- Sparse pages are expensive on Claude and Qwen. A page with one line on it costs 1,558 or 2,098 tokens as a file and a dozen as text.
- Dense pages are cheap on Gemini. A page of about 670 words costs the same 515 tokens as a blank one, while its text alone is about 800 tokens.
- On GPT-6 the file costs what the text costs, until a page has a picture. A scanned page, which is all picture, measured 2,868 tokens.
A 12-page report of plain text, about 250 words a page, came to 6,028 tokens as a file on GPT-6.1 Sol, 6,441 on Gemini 3.8 Flash, 27,297 on Claude Sonnet 5.5 and 30,934 on Qwen 3.8 Flash. Its extracted text was 5,924 to 8,716 tokens on all fifteen models.
When does extracted text fail?
On anything that is not in the text layer. Every question was tagged by what it needs, and the fifteen models are pooled:
| Route | Running text | Table cell | Chart | Scanned page |
|---|---|---|---|---|
| Extracted text | 297 of 300 | 168 of 170 | 0 of 150 | 0 of 105 |
| OCR, then text | 104 of 105 | |||
| PDF as a file | 186 of 186 | 103 of 103 | 90 of 90 | 62 of 63 |
| Page images, 110 dpi | 258 of 260 | 148 of 148 | 130 of 130 | 89 of 91 |
| Page images, 72 dpi | 257 of 260 | 142 of 148 | 130 of 130 | 88 of 91 |
Dots per inch (dpi) is the resolution a page is rendered at; 72 dpi makes a US Letter page 612 by 792 pixels. OCR is optical character recognition, software that reads text out of an image; we ran the open-source Tesseract locally.
Extracted text scored zero on charts and on the scan, on every model, because the numbers are not in the text. OCR recovered the scanned report at text price but not the charts: OCR of a 15-slide chart deck scored 0 of 7 on both models we gave it to. Tables survived extraction here because ours are simple grids. Merged cells and wrapped columns are harder, so test your own.
How do you pay less for documents?
Seven ways, six of them measured.
1. Pick the route from the counting rule. Text for pages that are only text. Otherwise the file on Gemini and 72 dpi page images elsewhere, because a page image costs the same however much is printed on it. A dense 6-page IRS form is 13,635 tokens as text on Claude Sonnet 5.5, 22,871 as a file and 4,015 as 72 dpi images, with all three questions right each way.
2. Route page by page. A real document mixes page types, and the kind function above sorts them: text pages go in as text, pages with a picture as 72 dpi images, scanned pages through OCR. On a nine-page document (four text pages, three charts, two scanned) with 12 questions:
| Model | As a file | Routed page by page | All pages as 72 dpi images |
|---|---|---|---|
| GPT-6 Luna | 15,106, 12 right | 5,140, 12 right | 5,750, 9 right |
| Claude Sonnet 5.5 | 17,228, 12 right | 6,543, 12 right | 6,257, 12 right |
| Qwen 3.8 Flash | 25,036, 12 right | 5,313, 12 right | 4,710, 12 right |
| Gemini 3.8 Flash | 5,043, 12 right | 7,110, 12 right | 10,278, 12 right |
Routing cut the input by 62% to 79% against the file on three vendors and kept every answer. On Gemini the file is already the cheapest.
3. Lower the image resolution, but not on text. Tokens for a page image fall with its pixel count, except on Gemini, which billed the same at every size. Chart slides with large labels held up at 36 dpi, where all six models we tried answered at least 6 of 7 and 15 slides cost 2,874 tokens on Claude Haiku 5.5 against 23,949 as a file. Body text needed 72 dpi: at 50 dpi Claude Haiku 5.5 and Gemini still answered 7 of 7, and GLM 5.3 Flash fell to 2 of 7. GPT-6 Luna lost answers on page images at every size below 96 dpi, so give it the file or text.
4. On OpenAI, set detail to low for picture pages. The Responses API takes a detail field on a PDF file. With low, GPT-6 Luna read the 15-slide deck in 9,985 tokens where the default took 22,155, and the scanned report in 11,387 where the default took 34,396, with every answer right. Pages of plain text were unchanged.
5. Send only the pages you need. For a 120-page manual, GPT-6 Luna read the extracted text (46,420 tokens) and named the page each of four questions needed. Claude Sonnet 5.5 then answered all four from a 4-page PDF of 8,758 tokens. The whole file is 253,822 tokens on Claude, so the input cost went from $0.508 to $0.022 including the first pass.
6. Let a cheap model transcribe and a large one reason. A cheap vision model turned the 15 chart slides into Markdown tables for $0.002 to $0.011. Claude Opus 5.5 then answered all seven questions from a transcript of about 2,000 tokens for $0.010, where the file is 23,949 tokens and $0.096 of input. The transcript can be kept and asked again.
7. Cache the document, and batch what can wait. With a cache breakpoint on the PDF (the cache_control marker in Anthropic’s API), six questions to Claude Sonnet 5.5 cost $0.117 against $0.461: the first wrote 38,364 tokens to the cache and the next five read them for about $0.004 each. Batch processing is the one we did not measure. OpenAI, Anthropic and Google each list their batch API at half price for results within 24 hours, and Anthropic says the discount stacks with caching.
One price line to watch: a 120-page PDF is over 250,000 tokens on Claude, and on Claude Haiku 5.5 a prompt over 100,000 tokens is billed at five times the price. The extracted text of the same manual is 68,382 tokens.
What do you do with a Word file?
Convert it. Of six models we tried, only GPT-6.1 Sol and GPT-6 Luna accepted a .docx as a file, and they read its text only, which is what OpenAI documents for files that are not PDFs. Converting to Markdown with pandoc is enough for text and tables: a nine-page contract came to 3,144 tokens and every model answered 7 of 7. A memo with an embedded chart scored 2 of 5 that way and 5 of 5 after converting to PDF with LibreOffice, at 1,217 tokens on Gemini 3.8 Flash and 3,827 on Claude Sonnet 5.5.
How we measured
Ten documents: seven generated (a 12-page report, 8 pages of financial tables, a 15-slide chart deck, the report as a scan, a 120-page manual, a Word contract and a Word memo) and three public ones (the paper “Attention Is All You Need”, IRS Form W-9 and NIST’s AI Risk Management Framework), each with three to seven questions that have one checkable answer.
The main run sent each document by each route to each model in one request: 568 requests on October 10, 2026, of which 566 succeeded (GPT-6 Luna refused 120 page images twice). The counting rules and the cost measures are a further 176 requests the same day, on one low-priced model per vendor. Everything went through the Synthorai gateway’s OpenAI-compatible chat endpoint, except the caching test (Messages API) and the detail test (Responses API). Dollar figures use list prices.
Token counts are what the endpoint reported on this route. Another provider of the same model can pre-process files differently, so run the six-page test on your own route before relying on a rule. With three to seven questions per document, a route that got everything right is readable, not proven lossless.
FAQ
How many tokens is a PDF page?
It depends on the vendor. Sent as a file, a page costs its text plus about 15 tokens on GPT-6, its text plus 1,558 on Claude, a flat 515 on Gemini with the text free, and about 2,098 plus the text on Qwen 3.8. A scanned page measured 2,868 tokens on GPT-6.1 Sol and 1,579 on Claude Sonnet 5.5.
Is it cheaper to send a PDF or its extracted text?
For pages of plain text, the extracted text is cheaper or equal everywhere except Gemini, where a dense page costs fewer tokens as a file because the text is not counted. On GPT-6.1 Sol the file costs almost the same as the text. Extracted text cannot answer questions about charts or scanned pages.
Can an LLM read a scanned PDF?
Yes, if it gets the pages as a file or as images. Extracted text is empty for a scan and scored 0 of 105 in our test. Running OCR locally and sending the result scored 104 of 105 at text price, the cheapest route for a scan of printed text.
Which models accept PDF files directly?
In our test, GPT-6.1 Sol, GPT-6 Luna, the three Claude 5.5 models, Gemini 3.1 Pro, Gemini 3.8 Flash, Qwen 3.8 Max and Qwen 3.8 Flash. DeepSeek V4.1 Flash, GLM 5.3 Flash, Kimi K3 and Qwen 3.6 35B took page images but not the file.
How do I reduce the cost of a long PDF?
Send fewer pages, send each page the cheapest way, and reuse what you send. A cheap model picking the relevant pages cut a 120-page request on Claude Sonnet 5.5 from 253,822 input tokens to 8,758. Routing pages by type cut a mixed document by 62% to 79%. Caching cut six questions on one document from $0.461 to $0.117.
Related reading
- How many tokens is an image?: the image billing rules that the page-image route follows.
- Claude Haiku 5.5 pricing: the 100,000-token line a long PDF crosses.
- Prompt cache write cost: what the first request of a cached document pays.