What actually eats your context window

What actually eats your context window

We run Claude Code across dozens of projects and we've built production RAG systems for clients handling millions of tokens per day. Along the way, we've noticed that almost everyone, including experienced engineers, has wrong intuitions about what actually fills up a context window. Take the quiz below. We bet you'll get at least two wrong.

Round 1: Reading a file into context

The question: You ask Claude Code to read a 500-line Python file. How many tokens does that cost?

Most people guess "not much, it's just a file read command." Some even think the file gets compressed or summarized before entering context.

The answer: Roughly 5,000 tokens. Every character of that file goes straight into the conversation as plain text. There's no compression, no summarization, no magic. Claude Code runs cat (or its internal Read tool), and the entire file content lands in your context window as if you had typed it yourself.

A 500-line Python file is about 15 KB of text. At roughly 3.5 characters per token, that's around 4,300 to 5,500 tokens depending on variable name lengths and comment density. Read three files to understand a bug, and you've burned 15,000 tokens before writing a single line of code.

Key Insight

File reads are the silent context killer. Every file Claude reads stays in the conversation history. Read ten files across a debugging session and you've consumed 50,000+ tokens just on code that's sitting there, being "attended to" on every subsequent prompt.

Round 2: Uploading a screenshot

The question: You paste a screenshot of a bug (1280×720 pixels, typical browser screenshot) into Claude. More or fewer tokens than that 500-line Python file?

Most developers think images are expensive because they're large files. A 1280×720 JPEG is 200 KB on disk, ten times larger than that Python file.

The answer: About 1,200 tokens. Far less than the Python file. Claude doesn't process images pixel by pixel. Its vision encoder splits the image into 28×28 pixel patches and compresses each patch into a single "visual token." A 1280×720 image becomes ⌈1280/28⌉ × ⌈720/28⌉ = 46 × 26 = 1,196 visual tokens. Your 500-line Python file costs four times more context than a full browser screenshot.

This surprises almost everyone. We had a client who avoided sending screenshots to Claude because they assumed images were "token-heavy." They were manually describing UI bugs in text instead, often using more tokens on the description than the screenshot would have cost.

But there's a tradeoff. Those 28×28 patches are lossy compression. Each patch summarizes 784 pixels into a single token. For a UI layout, a chart, or a diagram, that's more than enough. The visual structures are big enough to survive the compression. But for a screenshot of a logfile with 8pt monospace text? Claude is squinting at a blurry version of what you see clearly on your screen. Small text, dense tables, tiny UI elements: those can get mangled.

The practical rule: if you can read it comfortably at arm's length from your monitor, Claude can probably read it too. If you'd need to zoom in, paste the text directly instead. Text in context is expensive but lossless. Images are cheap but lossy.

What Works

Screenshots are cheap and great for layouts, charts, and visual bugs. But for anything with small text or dense data, paste the text directly. You'll spend more tokens, but Claude will actually read every character.

Round 3: Downloading a video

The question: You ask Claude Code to download a 500 MB video file from a URL. How many tokens does that cost?

This is the one where people's intuitions are most wrong. A 500 MB file sounds enormous. It must eat a huge chunk of the context window, right?

The answer: About 20 tokens. Claude Code runs curl -o video.mp4 "https://example.com/video.mp4" in the terminal. That command is roughly 20 tokens. The 500 MB file downloads to your hard drive. It never enters the context window. Claude doesn't "see" the file contents. It just executes a shell command, the same way it runs git commit or npm install.

The same applies to uploading files, moving them between folders, converting formats with ffmpeg, or zipping directories. Claude runs terminal commands that cost a few tokens each. The actual file data flows through your operating system, not through the language model.

Key Insight

There is a fundamental difference between "Claude processes this data" and "Claude tells your computer to move this data." File operations are shell commands. Only what Claude reads into the conversation costs tokens.

This is why Claude Code can handle workflows with gigabytes of data without breaking a sweat. It orchestrates your system. It doesn't ingest your system.

Round 4: JSON versus plain text

The question: You have a list of 100 customer records. You can send them as a JSON array or as a plain text table. Which format uses more tokens?

The answer: JSON uses roughly 2x the tokens of plain text for the same data. All those curly braces, quotes, colons, and commas add up fast. A JSON object like {"name": "Acme Corp", "revenue": 500000, "country": "CH"} is 56 characters. The same data as a tab-separated line, Acme Corp\t500000\tCH, is 21 characters.

We learned this the hard way on a RAG project. Our retrieval pipeline returned results as structured JSON with nested metadata. Switching the prompt format to a simple markdown table cut token usage by 40% with zero impact on answer quality. The LLM doesn't need curly braces to understand structured data.

// JSON format: ~2,800 tokens for 100 records
[{"name": "Acme Corp", "revenue": 500000, "country": "CH"}, ...]

// Markdown table: ~1,400 tokens for the same 100 records
| Name      | Revenue | Country |
| Acme Corp | 500000  | CH      |

Round 5: Your system prompt

The question: Your CLAUDE.md is 200 lines of project instructions. How often do those tokens get charged?

The answer: On every single API call. This is the one most teams underestimate. A 200-line CLAUDE.md is roughly 2,000 tokens. In a 30-message conversation, that's 60,000 tokens spent just on repeating the system prompt. With Claude Sonnet at $2 per million input tokens, that's $0.12. Sounds tiny, but across 500 conversations per month, it's $60 just on system prompt repetition.

The real cost isn't money though. It's attention. Research from 2025 showed that longer irrelevant context degrades model performance even when the relevant content is present in the window. Your 200-line CLAUDE.md about email formatting rules is actively making Claude worse at debugging your React components.

Common Mistake

Every token in your system prompt competes for attention on every single turn. A bloated CLAUDE.md doesn't just cost money. It makes the model measurably worse at the task you actually care about.

Round 6: Output versus input

The question: Claude writes a 100-line function for you. Is that cheaper or more expensive than the 500-line file you fed it as input?

The answer: A 100-line output costs roughly the same number of tokens as a 100-line input (about 1,000 tokens). But output tokens cost 5x more per token across every Claude model. So that 100-line function Claude writes costs you 5x more in dollars than reading 100 lines of input.

This is why streaming long outputs is the most expensive thing you can do with an LLM. A single verbose response that could have been 20 lines but rambles to 200 lines doesn't just waste your time. At $10 per million output tokens on Sonnet, those extra 180 lines cost real money. Over thousands of requests, the difference between a concise and a verbose system prompt for output formatting is significant.

Round 7: Conversation history

The question: You're on message 20 of a debugging session. How much of the conversation is Claude seeing?

The answer: Everything. Every message, every file read, every code block, every error trace. By message 20, a typical Claude Code session has accumulated 50,000 to 100,000 tokens of history. And all of it gets sent with every new prompt.

This is why long sessions get slow and expensive. It's also why Claude Code compresses earlier messages when approaching context limits. But compression is lossy. Details from message 3 might get summarized or dropped entirely by message 25.

The practical lesson: start a new session when switching tasks. A fresh context is faster, cheaper, and more accurate than a bloated one carrying the memory of three unrelated debugging sessions.

The cheat sheet

WhatToken costSurprise factor
500-line Python file~5,000 tokensPeople underestimate this
1280×720 screenshot~1,200 tokens (lossy)Cheap but can't read small text
500 MB file download~20 tokensIt's just a shell command
100 records as JSON~2,800 tokens2x more than plain text
100 records as markdown~1,400 tokensUse this instead
200-line CLAUDE.md~2,000 tokens × every turnThe hidden multiplier
100-line output~1,000 tokens × 5x priceOutput is 5x more expensive

What we changed after learning this

We restructured every production system around these numbers. RAG retrieval formats switched from JSON to markdown tables. System prompts got audited and trimmed (we wrote about using hooks for tool-specific context instead of bloating the main prompt). Client projects now have token budgets per conversation turn, not just per month.

The biggest insight is simple: tokens are not bytes. A 200 KB image costs fewer tokens than a 15 KB Python file. A 50-word JSON object costs more tokens than a 50-word sentence. And output tokens cost 5x more than input tokens across every major provider.

Once you internalize these numbers, you stop guessing and start measuring. That's when context management goes from an afterthought to an actual engineering discipline.

If you're building AI systems and want to optimize your token economics, get in touch.

More articles

How we use Claude Code hooks to keep context clean

Stop dumping every rule into CLAUDE.md. Hooks inject tool-specific context only when the agent actually needs it.

Read more

Building an AI Research Platform: ETL, RAG, and a Chatbot That Actually Knows Your Data

How we built a research data platform that ingests data from APIs, CSVs, and public databases into a unified schema, then lets researchers chat with it using RAG and MCP.

Read more

Tell us about your project

Contact

  • Location
    Switzerland
  • Working
    Remote & On-site