Context Window Economics: Why Stuffing 1M Tokens Into Gemini Isn't a Strategy
Million-token context windows look like they kill RAG. They don't. Here's what actually happens to accuracy, latency, and your bill when you stop retrieving and start stuffing.
Every few months a vendor ships a bigger context window and someone on your team asks: do we even need RAG anymore? Gemini can swallow a million tokens. Claude handles 200K comfortably. Just paste the whole knowledge base in, right?
We've tried it on real client workloads. The answer is more interesting than yes or no.
The pitch vs the invoice
The long-context pitch is seductive: skip the vector DB, skip chunking, skip reranking, skip the embedding pipeline, skip the whole retrieval tax. Fewer moving parts, fewer bugs, better recall because the model sees everything.
Then you check your bill.
At current public pricing (check Google's Gemini pricing and Anthropic's pricing before you commit — they change), a single query that stuffs 500K tokens of context into Gemini 2.0 Pro or Claude Sonnet costs real money. Not pennies. Multiply by a few thousand daily queries and you've built a product whose unit economics only work if your customers are enterprises paying four figures a month.
RAG, by contrast, typically sends 2K–8K tokens of retrieved context per call. The cost difference is roughly two orders of magnitude. That gap doesn't disappear because context windows got bigger; if anything, it widened, because the big-context tier is priced at a premium.
Prompt caching changes the math — partially
Both Anthropic and Google now offer prompt caching (see Anthropic's prompt caching docs and Gemini's context caching). If you're hammering the same 300K-token document with many questions, cached input tokens drop to a fraction of the base rate.
This genuinely shifts the tradeoff for workloads like:
- Legal review of one contract across many questions
- Codebase Q&A where the repo is stable for hours
- Analyzing a single long transcript or report
It does not shift the tradeoff for workloads where every query touches a different slice of a large, changing corpus. That's still RAG territory.
What actually happens to accuracy at 500K+ tokens
The "needle in a haystack" marketing graphs look great. Reality is messier.
In our experience building retrieval systems for document-heavy clients, long-context accuracy degrades along patterns the benchmarks don't capture:
- Multi-hop reasoning gets worse faster than single-fact lookup. Finding one quoted sentence in 400K tokens works. Synthesizing three facts scattered across the document works less well.
- Position bias is real. Content in the middle third of a very long context gets underweighted. This is well-documented in the "lost in the middle" literature and still shows up in 2026 models, though it's less severe than in 2023.
- Distractors tank precision. If your corpus contains near-duplicates, outdated versions, or contradictory passages, the model will confidently pick the wrong one. RAG with a decent reranker lets you filter these before the model sees them.
- Instruction following weakens. System prompts fight for attention against hundreds of thousands of tokens of content. We've seen models ignore output format rules on long-context calls that they followed perfectly at 10K tokens.
None of this means long context is broken. It means "just stuff everything in" is a strategy that works until it quietly doesn't, and you find out via a customer support ticket.
Latency: the silent killer
Cost gets attention. Latency gets ignored until users complain.
Time-to-first-token on a 500K-token prompt is seconds, not milliseconds, even with caching warmed up. For a chat UI, that's painful. For an agent loop that makes 5–10 model calls per task, it's disqualifying.
Rough shape of what we see in production:
- 4K-token RAG call: ~400–900ms to first token
- 50K-token call: ~1–2s
- 500K-token call (cached): ~2–5s
- 500K-token call (uncached): ~10–30s
If your product is "ask a question, get an answer," users will tolerate 2 seconds. They will not tolerate 15. And the uncached hit is what new users experience — the exact people whose first impression matters most.
A decision framework that survives contact with reality
Here's the rough decision tree we use when a client asks "long context or RAG?"
Is the relevant content stable per-session and < 500K tokens?
├── Yes → Long context + prompt caching is probably fine
│ (contract review, single-codebase Q&A, document chat)
│
└── No → Does the corpus change frequently or exceed 1M tokens?
├── Yes → RAG. Full stop.
│
└── No → Hybrid: retrieve to ~50–100K tokens,
let the model do the heavy lifting from there
The hybrid middle path is where most production systems actually land. Retrieval doesn't have to mean five chunks of 500 tokens each. It can mean "the three most relevant documents in full, totaling 60K tokens." That gives the model enough context to reason across sections without paying for the entire corpus every call.
A concrete example
Say you're building internal search over a 20M-token knowledge base — Confluence, Slack exports, PDFs, the works.
Naive long-context approach: impossible. The corpus doesn't fit, and even if it did, every query would cost dollars.
Naive RAG approach: chunk everything to 500 tokens, embed, retrieve top 10, stuff into prompt. Works, but struggles with questions that need broad context ("summarize our Q3 roadmap decisions").
What we'd actually build:
# Pseudocode, not production
def answer(query: str) -> str:
# 1. Classify intent — narrow fact vs broad synthesis
intent = classify(query) # cheap model call
if intent == "narrow_fact":
# Standard RAG: tight chunks, reranker, 5-8K context
chunks = hybrid_search(query, k=20)
top = rerank(query, chunks)[:5]
return llm.generate(query, context=top, model="fast")
if intent == "broad_synthesis":
# Retrieve whole documents, not chunks
docs = document_level_search(query, k=3)
# Cache the doc payload if query volume justifies it
return llm.generate(
query,
context=docs,
model="long_context",
use_cache=True,
)
Two pipelines, one router. The router itself is a sub-cent call to a small model. Costs stay bounded, latency stays acceptable, and the broad-synthesis queries actually work instead of returning five disconnected chunks the user has to stitch together.
Model-specific notes for 2026
Gemini (1.5 Pro, 2.0 Pro, and successors): still the leader on raw context length and generally the cheapest per-token at the long end. Context caching is strong. Weakest on strict instruction following at extreme lengths in our testing — budget time for prompt hardening.
Claude (Sonnet 4.x, Opus 4.x): 200K window, excellent instruction following across that full range, prompt caching with aggressive TTLs. Our default when the content fits and reasoning quality matters more than raw size.
OpenAI (GPT-4.1 / GPT-5 family): context windows have grown but pricing at the long end is less competitive than Gemini. Strong tool-calling, which matters more for agent workloads than for pure Q&A.
Don't take any of this as a leaderboard. Run your own evals on your own data — we've written about building golden sets your team will maintain and it's the single highest-leverage thing you can do before picking a model.
The cost guardrails we actually set
Regardless of architecture, hard limits in code:
- Per-request token cap (reject or truncate before the API call, not after)
- Per-user daily spend cap tracked in your own metering, not the vendor's
- Alerting on p95 token usage, not just average — long-tail queries are where bills explode
- A "big model" allowlist: only certain endpoints or user tiers can trigger the expensive path
Without these, one buggy loop or one adversarial user can produce a four-figure bill overnight. We've seen it. It's not fun to explain.
Where we'd start
If you're staring at this decision on a real project: measure first, architect second. Take your 50 hardest real queries, run them through a cheap RAG baseline and a long-context stuffed baseline, and score the outputs against a golden set. Log cost and latency per call.
Nine times out of ten the answer is a hybrid: RAG for the common path, long-context with caching for the queries that genuinely need it, a cheap router deciding between them. The two-order-of-magnitude cost gap is too big to ignore, and the latency gap is too obvious to users.
Bigger context windows are a tool, not an architecture. Treat them that way and your product — and your margins — will survive the next model release.
Want a team like ours?
72Technologies builds production software for the kind of teams who actually read this blog.
Start a projectKeep reading
Hybrid Search for RAG: Why BM25 Still Beats Pure Vectors on Half Your Queries
Pure vector search looks magical in demos and then fails on product SKUs, error codes, and names. Here's how we wire BM25 and embeddings together without regretting it six months in.
Evals That Catch Regressions: Building a Golden Set Your Team Will Actually Maintain
Most LLM eval suites die within a quarter because nobody owns them. Here's how to build a golden set your engineers will keep alive — and that actually catches regressions before your users do.

Streaming Tool Calls Without Breaking Your UI: A Practical Pattern
Streaming works great until your model emits a tool call mid-token-flush and your frontend starts rendering half a JSON blob. Here's the pattern we use to keep streams fast and UIs sane.
