# What a 1M-token context window means for your code

A million tokens is a number that does something strange to your judgment. It sounds like enough room to never think about context again. Just paste the whole repo, paste the docs, paste the logs, and let the model sort it out. That instinct is the trap. A bigger window raises the ceiling for real long-document work, but it does not change the physics underneath. This guide makes the number concrete, shows what fills it, and explains why a focused context still beats a stuffed one on both accuracy and cost.

## How big is a million tokens?

Start with the conversion. One token is about 0.75 words of English on average. So a million tokens is roughly 750,000 words.

To feel that number, put it next to something you know. The full Lord of the Rings trilogy runs around 480,000 words. The Hobbit adds about 95,000 more. Together that is roughly 575,000 words. A 1-million-token window comfortably holds all four books and still has room for another 175,000 words on top. You could feed a model every page Tolkien wrote about Middle-earth's main saga and not fill the window.

That is the mind-blowing part. The reality check is the next sentence: you almost never want to.

## Is a bigger context window a free pass to paste everything?

The window is the maximum the model can hold at once. It is not a target to hit. Think of it the way you think of memory on a machine: having 64 GB does not mean you should load a 60 GB file because you can. Every token you place in the window has to be read, attended to, and paid for on every single request.

Here is what a million tokens looks like translated into code, where most of your context comes from.

| What you put in the window | Rough token cost |
|---|---|
| One short config or types file | 200 to 800 tokens |
| One medium source file | 1,500 to 4,000 tokens |
| A long file with comments and tests | 5,000 to 12,000 tokens |
| A 100-file repo dump | 200,000 to 600,000 tokens |
| A full conversation, 30 turns with code | 30,000 to 80,000 tokens |
| Lord of the Rings + The Hobbit | ~770,000 tokens |

Read the table the other way and the scale clicks. A medium source file is a rounding error against a million. A whole-repo dump can eat half the window before you have asked a single question. The window is large, but real codebases are larger than they feel, and the moment you start dumping, the budget disappears fast.

## What gets missed when you stuff the context window?

The first assumption to drop is that the model reads a 600k-token dump the way you would read a single function. It reads all of it, but not evenly.

### A worked example: the bug hiding in the dump

Picture a service with about 220 files. There is a token-refresh bug: under a clock skew of a few seconds, an expired session is treated as valid. The fix lives in one function, `isSessionValid`, inside `src/auth/session.ts`. The behaviour that defines "correct" lives in one test, `src/auth/session.test.ts`, where line 40 documents the skew tolerance. There is also a one-line comment three files away in `src/auth/clock.ts` explaining why the tolerance exists at all.

Now dump the whole service into the window. That is roughly 480,000 tokens. You ask: "Why does an expired session sometimes pass?"

Here is what is competing for the model's attention. The router, the database layer, the email templates, the billing code, two hundred files of perfectly real code that have nothing to do with this bug. The three things that matter, the function, the test on line 40, and the clock comment, are short, scattered, and sitting in the middle of the pile. The model can technically see all of them. In practice it is far more likely to produce a plausible-sounding answer about a different file, miss the line-40 invariant entirely, and never connect the clock comment to the bug. You did not give it more help by sending more. You buried the help you had.

Run the same task with two files named explicitly and the model finds the bug almost immediately, because nothing is hiding it. Same model, same skill. You changed what you put in front of it.

The failure mode is worth naming precisely, because it does not look like failure. The dumped session does not say "I cannot find it". It gives you a confident, well-written answer that points at the wrong file, or invents a plausible cause that the code does not contain. A dump invites this. With four hundred thousand tokens of real code in view, there is always some function that looks related enough to blame, and the model reaches for it rather than admitting the signal was too thin. The focused session has nowhere to wander, so when it is unsure it tends to say so. Less context does more than raise the odds of a right answer. It lowers the odds of a confidently wrong one.The trap is reading a dump's fluent, well-cited answer as a correct one and shipping the fix it names. A stuffed window almost never says "I could not find it"; it blames a plausible nearby file instead. Before you trust an answer from a large paste, re-run the same question against just the two or three files you think are load-bearing, and if the two answers disagree, believe the focused one.

### Lost in the middle

Models recall content placed near the start and the end of a long context more reliably than content buried in the middle. This is the lost in the middle effect, and it gets worse as the context gets longer.

The shape of it is a U. Put a fact in the first few thousand tokens and recall is strong. Put the same fact in the last few thousand tokens, right before the question, and recall is strong again. Put it at the 50% mark of a 400k-token dump and recall sags hard. That is the worst place a fact can be, and it is exactly where a buried function in a repo dump tends to land. The model has not lost the ability to read it. It is weighting it as if it were background.

This is why ordering matters as much as inclusion. If something is critical, its position in the window changes how reliably it is used, as well as whether it is present. The discipline of putting the load-bearing material where attention is strongest is the heart of [context engineering](/guides/context-engineering).

### Dilution

A repo dump is mostly noise relative to any single task. If you are fixing a bug in `src/auth/session.ts`, the other two hundred and nineteen files are not context, they are distraction. They compete for the model's attention with the four lines that matter. One relevant function diluted among hundreds of irrelevant ones is harder to act on than the same function sent alone. More text does not mean a better answer. It frequently means a worse one, because the signal is buried.

There is a measurable version of this worth keeping in your head: the signal-to-noise ratio of the window. In the focused version of the auth task, the relevant tokens are maybe 80% of what you sent. In the dumped version, the relevant tokens are a fraction of a percent. The model is doing the same job in both cases, finding the few lines that matter, but in the dump it has to do that job against four hundred thousand tokens of decoys. You would not hand a colleague the entire codebase printed out and ask them to find a four-line bug by reading cover to cover. You would point them at the file. The model deserves the same courtesy, and it answers better when it gets it.

### Skimmed edge cases

The subtle things you most want the model to notice, a buried test that documents a weird invariant, an edge case guarded three files away, a comment explaining why a hack exists, are exactly the things that get skimmed in a giant context. They are short, they are scattered, and they sit in the middle. The bigger the dump, the more likely the model treats them as background texture rather than load-bearing detail.

This is the cruel part of the tradeoff. The detail you would most want surfaced is, by its nature, the small and easily missed kind, and the dump is the environment most hostile to small things. A focused context flips that. In two files, a comment is not background, it is a quarter of what the model is looking at, and it gets read like it matters because it does.

## Every token is billed, every request

Accuracy is only half the cost of stuffing. The other half shows up on the bill.

In a multi-turn session the entire context is resent on every turn. That is the part people forget. You pay for a 400k-token dump when you paste it, then again on turn two, turn three, and every turn after, because the model has no memory between requests beyond what you send. The window is rebuilt and rebilled each time.

Set the dump next to a focused context and the gap is stark. A 400k-token context costs roughly 40 times what a tight 10k-token context costs per request, before you have done anything different with the answer. Now play it forward over a real session.

| Scenario | Tokens per turn | Turns | Relative input cost |
|---|---|---|---|
| Targeted context, one shot | ~10,000 | 1 | 1x |
| Targeted context, 10 turns | ~10,000 | 10 | ~10x |
| Whole-repo dump, one shot | ~400,000 | 1 | ~40x |
| Whole-repo dump, 10 turns | ~400,000 | 10 | ~400x |

The bottom row is the one that should sting. Ten turns of debugging on a dumped repo can cost on the order of four hundred times a single focused request, and it tends to answer worse the whole way through. Multiply that again by an agent loop running hundreds of iterations and the difference between targeted and stuffed context stops being a rounding error and becomes the entire invoice. The full accounting of how multi-turn cost compounds, and where caching does and does not help, is in [token usage and cost](/guides/token-usage-and-cost).

| Approach | Tokens per request | Relative cost | Accuracy risk |
|---|---|---|---|
| Targeted context | ~10,000 | 1x | Low, signal is clean |
| Moderate over-include | ~100,000 | ~10x | Medium, some dilution |
| Whole-repo dump | ~400,000 | ~40x | High, lost in the middle |

Latency rises with the same curve. The model has more to read before it can begin answering, so a stuffed context is slower to first token as well as more expensive. A 10k-token prompt feels near-instant; a 400k-token prompt makes you wait while the model works through everything you sent before it writes a word. A large window does not make a large prompt free or fast. It makes the large prompt possible.

A fair objection: does caching not fix the bill? Partly, and only sometimes. Prompt caching can make the repeated portion of a context much cheaper to resend, which helps when a large stable prefix stays byte-for-byte identical across turns. But two things break that in practice. The first is that interactive coding work edits the context, and any change near the front invalidates everything after it, so the cache rarely survives a real debugging session intact. The second is that caching does nothing for the accuracy problem. A cached 400k-token dump is cheaper than an uncached one and still loses the function in the middle. Caching is a discount on a decision you should not have made, not a reason to make it.Do not justify a giant paste with "caching covers it." Editing anything near the top of the context busts the cache for everything after it, so a live debugging session rarely keeps the discount, and caching never fixes the buried-in-the-middle accuracy hit. Keep the window lean first, treat any cache savings as a bonus.

## The slow drift of a fat window

There is a third cost that only shows up over time, and it is the one that surprises people running long sessions or agent loops. As a context grows, the model's grip on its own instructions loosens. A rule you stated clearly in the first turn, "do not change the test", "always run the build before reporting done", competes with everything that piled in afterward. By turn twenty of a session that has accreted two hundred thousand tokens, that rule is a faint voice near the start of a very long room.

This is the same lost-in-the-middle physics, applied to your own directions rather than to the code. The instruction is still in the window. It is no longer near where attention is strong, and it is surrounded by a wall of intervening text. The practical symptom is an agent that was sharp early and gets sloppier the longer it runs: ignoring constraints it followed at first, repeating work, forgetting a decision made an hour ago.

The fix is not a bigger window. A bigger window makes the room longer, not the voice louder. The fix is to keep the working context lean, restate load-bearing constraints when they start to slip, and reset between phases of work rather than letting one session sprawl across unrelated tasks. The CLI controls in the next section exist precisely for this.

## When should you use the big context window?

None of this means the window is wasteful. It means the window is for the cases that need it. A 1-million-token context is the right tool when the relevant content is large and all relevant.

- A single long document you need analysed end to end: a contract, a spec, a transcript, a book-length report.
- A large file or a tightly coupled set of files where the task spans all of them, not a dump of unrelated neighbours.
- A long session you want to keep coherent without losing earlier decisions, where the history itself is the context.

The distinction is relevance, not size. Long-document work is legitimate and the big window unlocks it. A repo dump is not long-document work. It is many short irrelevant documents wearing a trench coat. The decision of when to retrieve a focused slice versus paste a large block is worth its own walk-through in [context injection vs. stuffing the window](/guides/context-injection-vs-stuffing).

To make the legitimate case concrete: say you have a 90-page vendor contract and you need to know whether the termination clause conflicts with the auto-renewal clause. Those clauses might be sixty pages apart, and the answer depends on reading both in full, with all the defined terms that bind them. There is no clean way to grep your way to a correct answer here, because the conflict is a property of the whole document, not of a keyword. This is what the big window is for. The content is large, it is one document, and the relevant span is most of it. Pasting the whole contract is the right move, not a lazy one. The test is always the same: not "is this big" but "is all of this the thing I am asking about".

## Targeted context beats stuffing

The reliable pattern is the same one that worked before windows got large: put the signal in the window and leave the noise out. Retrieve what the task needs instead of dumping what might be related. If you are deciding between pulling in a focused set of files and pasting everything, that tradeoff is exactly the subject of [RAG or a long prompt](/guides/rag-or-a-long-prompt).

Concretely, name the files instead of the repo:

Read src/auth/session.ts and src/auth/session.test.ts. The test on line 40 is failing. Fix the session logic without changing the test.

That loads two files. The model sees the bug, the test that defines correct behaviour, and nothing else competing for attention. The same task with a whole-repo dump costs 40 times as much and answers worse, because the two files that matter are now hiding among hundreds that do not.

When you do not know the exact file, describe the subsystem and let the tool search rather than pre-loading everything:

Find every place we call spawnWorker and list the file paths and line numbers. Do not change anything yet.

The tool greps, reads only the matching files, and reports back. Only the relevant excerpts land in the window. This is the key shift: the search tool, not your paste buffer, decides what enters the context, and it pulls in matches instead of everything around them.

This is retrieval-on-demand, and it scales in a way pasting never does. A repo dump is fixed at the size of the repo whether the task needs ten lines or ten thousand. Search loads what the current question needs and nothing more, so the window stays roughly constant no matter how large the codebase grows underneath it. You can work in a million-line repo with a ten-thousand-token window, because the window holds the slice you are working on, not the repo. That is the whole trick, and it is why naming a subsystem and letting the tool find the files beats trying to front-load the answer.

You found three call sites. Read only the one in the queue module and explain why it passes a null worker id.

Notice the second prompt narrows again. Each step adds only the next slice the task needs, instead of holding all three call sites resident for a question that touches one. The context tracks the work, turn by turn, rather than ballooning to cover every branch you might take.

### Three ways to fill the window

Almost every context decision in coding is a choice between three moves, and naming them makes the choice easier to get right.

Dumping is the default people reach for and almost never the right one. Pasting named files is right when you already know exactly which files matter, which is more often than it feels once you have looked. Letting the tool search is right when you do not, and it is the move that scales as the codebase grows. The skill is recognising which situation you are in before you act, rather than dumping out of habit and hoping the window absorbs the consequences.

## CLI mechanics that keep the window honest

Claude Code gives you a few controls that make targeted context the default instead of a thing you have to remember.

**See what is in the window.** Run `/context` to view how the current window is filled and where the tokens are going. Surprises are common. A reference file you forgot you loaded, a conversation that grew past where it was useful. You cannot prune what you cannot see.

```bash
/context
```

It helps to know what `/context` is even showing you, because the window is never just your prompt. A working session is built from several layers, and they add up before you have typed a thing.

| Layer | What it is | Roughly |
|---|---|---|
| System and tool setup | The base instructions and tool definitions | A few thousand tokens |
| Project memory | Standing rules and notes for the repo | Hundreds to thousands |
| Files you have read | Source loaded into the session | Varies, often the largest |
| Conversation history | Every prior turn, resent each time | Grows steadily |

The two rows that move are the bottom two, and they are the two you control. Files you read stay resident until you clear them, and the history only ever grows. Watching `/context` is how you notice the moment the window has quietly drifted from lean to bloated, which is almost always earlier than it feels.

**Reset or compress.** Use `/clear` between unrelated tasks to wipe the slate, and `/compact` mid-task to replace a long history with a dense summary that keeps the thread without the token weight.

```bash
/clear     # finished a task, starting an unrelated one
/compact   # deep in one task, history is getting heavy
```

The rule is simple: `/clear` between tasks, `/compact` within a task. Dragging an auth debugging session into a CSS layout task is pure noise, and it is billed on every turn until you clear it.

**Hand large reads to a subagent.** When a step needs to read a lot, like surveying many files to answer one question, delegate it to a subagent. The subagent works in its own fresh window, does the heavy reading there, and returns only its conclusion to your main session. The bulk of the tokens never touch your context.

This is how you get the benefit of reading widely without paying for it on every subsequent turn of the main thread, and it is the foundation for larger multi-agent setups. The mechanics of splitting work across fresh windows are covered in [how agents fan out](/guides/how-agents-fan-out). For the broader set of habits that make the big window work in your favour, see [advanced Claude Code techniques](/guides/advanced-claude-code-techniques).

The instinct each command serves is the same one this whole guide is built on. Keep the main window small and deliberate. Spend the big budget only where the task earns it.

## A pre-flight check before you paste

When you catch yourself about to drop something large into the window, pause and run three questions past it.

| Question | If yes | If no |
|---|---|---|
| Is the whole thing relevant to this one task? | The big window is fair game | Cut it down to the relevant slice |
| Could a grep or a search find the part I need? | Let the tool retrieve it | A targeted paste is fine |
| Will this stay loaded across many turns? | Be ruthless, it is billed every turn | A one-shot heavy read can go to a subagent |

The pattern under all three is the same. The big window is a tool for content that is both large and relevant, not a substitute for deciding what matters. Most of the time the honest answer is that you needed two files, not two hundred, and the work of figuring out which two is the work that makes the answer good.

## Check the current limit before you rely on it

One detail that will date faster than the rest of this guide: the exact number. Current Claude models support up to about 1,000,000 tokens of context. Which models offer it, and whether using it requires a specific flag or setting, both change over time as models are released and updated. Do not freeze a list from memory or from this page.

Check the official model documentation at [docs.claude.com](https://docs.claude.com) for the current limits and any requirements before you build around a specific window size. Treat the million-token figure here as the shape of the thing, not a guarantee for the model you happen to be running today.

## The takeaway

A million-token window is a real upgrade. It raises the ceiling for legitimate long-document work that used to be impossible to do in one pass. What it does not do is repeal the tradeoffs.

- A bigger window is a budget, not a free pass. Every token is read, attended to, and billed on every request.
- Stuffing hurts accuracy. Content in the middle gets lost, the one relevant function gets diluted, edge cases get skimmed, and a thin signal invites a confidently wrong answer.
- Stuffing hurts cost and latency. A 400k-token dump can cost around 40 times a focused 10k-token context per turn, and ten turns of it can run to hundreds of times the cost of a focused request.
- A fat window also drifts. Over a long session your own instructions slide towards the middle and get followed less reliably, so lean context keeps the model on track.
- Targeted context still wins. Name the files, let the tool retrieve, watch usage with `/context`, prune with `/clear` and `/compact`, and offload heavy reads to subagents.

The headline number is fun, and the Tolkien comparison is real. But the skill that matters is the same one it always was: decide what the model needs to see, and send that. The window got bigger so the rare hard cases became possible, not so the easy cases could get lazy.
