# Where Does RAG Actually Cost You Money? (Episode 2)

> Source: <https://dev.to/surajrkhonde/where-does-rag-actually-cost-you-money-episode-2-c1l>
> Published: 2026-07-27 11:04:01+00:00

I thought I had solved document extraction.

My Node.js project could pull text out of a PDF. The library was free. No API bill, no config, no drama. I ran it on a few sample docs, the text came back clean, and I moved on to the "real" parts of the pipeline — chunking, embeddings, retrieval.

Everything looked solved.

Until I uploaded a real corporate document.

The PDF opened fine. No errors. Text came back — a whole string of it, sitting right there in my terminal. Extraction "worked."

And then my RAG system answered a simple question completely wrong.

I did what anyone does — I blamed the usual suspects. Checked the LLM prompt. Checked the embeddings. Checked retrieval, checked the vector DB, checked if the right chunks were even being pulled.

All fine.

The bug wasn't in my LLM. It wasn't in my embeddings. It wasn't in retrieval.

It started much earlier than any of that.

**The parser had quietly destroyed the document before the rest of my pipeline ever got a chance to see it.**

That was the moment it clicked for me: document extraction was never about "reading a PDF." It's about **preserving knowledge** before anything downstream can use it. And preserving knowledge, it turns out, costs money.

Everything below comes back to one sentence:

Document extraction is the first place in the RAG pipeline where you make a quality-vs-cost decision — whether you realize you're making it or not.

Not "which library should I use." Not "OCR is hard." Just this: the moment a document enters your system, you're already choosing between cheap-and-lossy or expensive-and-faithful, and that choice quietly sets the ceiling for every stage that comes after it.

Here's the sequence that fooled me, laid out plainly:

```
Free parser
     │
     ▼
Table becomes word soup / column order scrambled
     │
     ▼
Chunk looks fine (no error, just wrong)
     │
     ▼
Embedding of a wrong chunk
     │
     ▼
Retrieved anyway — vector search doesn't know it's damaged
     │
     ▼
LLM answers confidently... and wrong
     │
     ▼
User asks again, rephrases, retries
     │
     ▼
More LLM calls, more tokens, more cost
```

Notice what's missing from that chain: an error message. A broken extraction almost never crashes anything. It just silently produces a confident, well-formatted, *wrong* answer — and the bill for that mistake doesn't show up on the extraction line. It shows up later, on the LLM line, disguised as "users retrying" or "hallucination rate."

That's the trap. The cost didn't disappear when you picked the free parser. It just moved to the most expensive stage in the whole pipeline and hid there.

Let's make this concrete instead of abstract.

Say you're processing **1 million pages a month.**

```
API bill:  $0/month
```

But:

`<Image>`

with zero textResult:

```
Bad extraction
     ↓
Users don't get their answer
     ↓
They ask again (2nd LLM call)
     ↓
They rephrase and ask a third time (3rd LLM call)
     ↓
Support ticket, because the bot "doesn't know" a document it clearly ingested
```

Your extraction bill is $0. Your **effective** cost per successfully-answered question just went up 2-3x, because you're paying for the LLM call three times to get one right answer.

```
Extraction bill: suppose it costs a few hundred dollars a month more
```

But:

Result:

```
Good extraction
     ↓
Right chunk retrieved the first time
     ↓
One LLM call, correct answer
     ↓
No retries, no ticket
```

Now run that logic across volume. If even a modest slice of queries under Option A need a retry — and each retry is a full LLM round-trip — the "free" parser can plausibly end up costing more in extra LLM calls than the paid extraction service would have cost outright. And that's before counting the users who just give up and stop trusting the bot.

**In that scenario, the "expensive" parser doesn't stay the expensive choice. It becomes the cheaper system.**

That's the whole game of this series: the line item you're worried about is rarely the one actually draining your budget.

There's another bill nobody invoices you for: engineering time. Every document type that breaks — a weird table layout, a scanned page with faint ink, a two-column report — becomes another edge case someone on your team has to notice, debug, test, and maintain. A free parser isn't really free if it quietly costs your team weeks of patching extraction bugs instead of building the product.

This is the part that changed how I think about extraction the most, and I almost skipped writing about it because it seemed too small to matter. It isn't.

Imagine every page of a 400-page bank document has this footer:

```
Confidential
Acme Bank
2025
```

Trivial, right? Except your parser doesn't know it's a footer. It just sees text, on every single page.

```
Page 1  →  "Confidential Acme Bank 2025" + real content
Page 2  →  "Confidential Acme Bank 2025" + real content
Page 3  →  "Confidential Acme Bank 2025" + real content
   ...
Page 400 → "Confidential Acme Bank 2025" + real content
```

That one sentence just got **embedded 400 times.** It now exists as 400 near-identical vectors sitting in your database, all clustered close together in embedding space.

Here's where it actually bites you: when someone asks a real question, "Confidential Acme Bank 2025" chunks are dense, repetitive, and semantically generic enough that they can crowd out the top-k slots that should've gone to your actual content. Retrieval keeps returning noise instead of knowledge — not because retrieval is broken, but because you fed it 400 copies of nothing.

```
Uncleaned boilerplate
       ↓
400 near-duplicate chunks
       ↓
Bloated vector index
       ↓
Noisy top-k retrieval
       ↓
Wasted context tokens sent to the LLM
       ↓
Higher bill, worse answers
```

Stripping headers, footers, page numbers, and watermarks before chunking isn't a cosmetic cleanup step. **It's a cost optimization** — and it's one almost nobody talks about, because it doesn't show up on any pricing page.

Once you start looking for this pattern, it shows up everywhere in corporate documents:

Each one follows the exact same chain:

```
More boilerplate  →  More chunks  →  More embeddings
        →  Bigger vector DB  →  More retrieval noise
        →  More LLM tokens  →  More money
```

None of these individually feel expensive. A logo isn't expensive. A page number isn't expensive. But multiply a few of these by hundreds of pages and thousands of documents, and you've quietly inflated your vector database and your retrieval noise for zero added knowledge. This is the kind of decision that's invisible in a demo with 3 sample PDFs and very visible once you're running 50,000 real documents in production.

Corporate documents today aren't just paragraphs of text. They're full of:

And here you hit the exact same fork in the road as everywhere else in this pipeline:

```
                Document contains an image
                         │
            ┌────────────┴────────────┐
            ▼                         ▼
      Ignore it                Run OCR + Vision
            │                         │
            ▼                         ▼
        Free                  Higher extraction cost
            │                         │
            ▼                         ▼
   Knowledge is gone          Knowledge is preserved
   ("Show me the payment      ("Show me the payment
    flow" → no answer)         flow" → correct answer)
```

Ignoring images is free right up until someone asks a question whose answer only exists inside a diagram. Then "free" extraction just means "the bot can't answer that," and you're back to the same retry loop as the table example above — except this time, no amount of retrying will fix it, because the knowledge was never captured in the first place.

Same fork, same trade-off, same underlying question every time: **are you willing to pay upfront for extraction quality, or are you going to pay downstream for the gaps it leaves behind?**

Every section in this article — tables, OCR, headers and footers, logos, diagrams — is really the same decision wearing a different costume:

You either pay a little more at extraction to preserve knowledge, or you pay a lot more later — in retries, in noisy retrieval, and in LLM tokens — to make up for what extraction quietly threw away.

Cheap extraction isn't actually cheap. It just defers the bill to the most expensive part of your pipeline and hides it inside a metric that looks unrelated, like "hallucination rate" or "average tokens per query."

That's the real reason document extraction deserves its own episode in a series about where RAG money goes. It's not the biggest line item. But it's the stage that decides how big every *other* line item gets to be.

I started this series believing embeddings were where RAG became expensive. Two episodes in, I'm realizing something very different — **every stage before the LLM quietly decides how much the LLM will eventually cost you.**

The cheapest parser was never the one with the lowest API price. It's the one that produces the fewest unnecessary LLM calls.

I trust my extraction pipeline a lot more now. But a new question showed up immediately:

**Once I have clean text — how should I even split it?**

Because bad chunking can destroy perfectly extracted knowledge just as easily as a bad parser can.

*Less noise, more action. Let's dig.*
