# Context Engineering

The context window is your primary lever for controlling model behaviour. Every token you send costs money, adds latency, and competes for the model's attention. Every token you leave out is one the model cannot use. Getting that balance right is context engineering.

## The window is a budget

Current Claude models support up to [1 million tokens of context](/guides/million-token-context-window). That sounds infinite. It is not. Real costs accumulate fast:

| What you send | Typical size |
|---|---|
| System prompt with rules + persona | 500–2,000 tokens |
| One medium TypeScript file | 1,500–4,000 tokens |
| Full repo dump (100 files) | 200,000–600,000 tokens |
| 30-turn conversation with code blocks | 30,000–80,000 tokens |
| One Claude response | 500–8,000 tokens |

A repo dump that fills 400k tokens costs roughly 40x more per request than a focused 10k-token context, and it dilutes signal with noise. The model does read everything you send. More text does not mean better answers; it often means worse ones because the relevant content is buried.

> Think of the window as a whiteboard. You can write anything on it, but the model reads the whole board before every reply. Keep it clean.

## What goes in the context window?

### Always include

- **The task.** A precise description of what you want, in plain language. Vague tasks produce vague outputs.
- **The constraint set.** Rules, style guides, type signatures, API contracts, error formats. Anything the model must not violate.
- **Directly relevant code.** The file being edited, the function being called, the schema being implemented. Not the whole codebase.
- **Recent conversation turns.** The last few exchanges, especially if they contain clarifications or partial work.

### Include conditionally

- **Examples.** One or two concrete input/output pairs beat three paragraphs of prose instruction. Include them when the task is ambiguous or novel.
- **Error messages.** Paste the full stack trace when debugging. Do not summarise it.
- **Test output.** Include when it shows a failure the model needs to fix.

### Exclude

- **Unrelated files.** If the model is editing `auth.ts`, it does not need `analytics.ts`.
- **Stale conversation.** Turns from 20 exchanges ago describing a direction you abandoned are noise.
- **Generated boilerplate.** Lock files, build artifacts, auto-generated types the model did not write and cannot improve.
- **Redundant docs.** Do not paste the README and then also paste the inline docstrings for the same functions.

## How should I order content in the context window?

The order of content in the window matters for two reasons: model attention and prompt caching.

### Attention

Claude attends to content near the beginning and end of the context more strongly than to content in the middle. Long documents buried in the middle of a 500k-token context are the most likely to be underweighted. Put your instructions and the most critical constraints early. Put the task request late, just before the assistant turn.

### Cache-friendly ordering

Claude Code builds the context window for you on every turn. The stable parts of that window (your `CLAUDE.md`, pinned files, tool definitions) are sent first and hit the prompt cache after the first request. The dynamic part (your current message) is always at the end.

```
[CLAUDE.md + .claude/ rules]  ← static, cache once
[@-mentioned files]            ← changes per task, stable within a session
[conversation history]         ← grows each turn
[current message]              ← always new
```

Cache reads cost 10% of the base input price. The maths tips strongly in your favour once the same static content repeats across more than a handful of turns. Claude Code exploits this automatically when content is stable; for the full mechanics, see [prompt caching](/guides/prompt-caching).Editing `CLAUDE.md` or swapping a pinned file mid-session feels harmless, but any change to the static prefix invalidates the cache from that point on, so the next turn re-bills the whole prefix at full input price instead of 10%. Make rule and pinned-file changes at a `/clear` boundary, not in the middle of a live task, so the cache stays warm for the turns that do work.

## How does Claude Code load context into a session?

Claude Code loads context from several sources before your first message lands. Understanding the priority order helps you put rules where they will stick.

**CLAUDE.md** is the right place for durable rules: coding conventions, folder structure, what to never do. Keep it short and precise. Every token in `CLAUDE.md` is loaded on every turn; for the full picture of what persists between runs, see [how Claude Code memory works](/guides/how-claude-code-memory-works).

**@-mentioning files** is the right move for task-specific context. Instead of asking Claude to explore the whole codebase, tell it exactly what to read:

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

This loads two files, nothing else.

## A well-shaped context

Static content (A, B) belongs at the top. Dynamic content (D, E) goes at the bottom and changes every turn. Relevant code (C) sits in the middle and changes per task but is stable within a session.

## Summarisation and compaction

Long agentic sessions accumulate history fast. A 30-turn session with tool calls and large outputs can reach 80,000 tokens before the task is half done. Two strategies address this.

### Explicit summarisation

At a natural checkpoint, ask Claude to summarise what has been decided so far, then use `/clear` to reset the conversation. Paste the summary back as your opening message for the next leg of work.

Summarise the decisions made and files changed so far in three to five bullet points. Be specific: include file names, function names, and any constraints discovered. I will use this summary to start a fresh session.

Run `/clear` after copying the summary. You recover the full window while keeping the essential working context.

### Rolling compaction with /compact

Claude Code has a built-in `/compact` command. Run it when the conversation is growing long but you are not ready to start fresh. It replaces the raw history with a dense summary that Claude writes about its own session state, preserving the task direction without the token weight of every intermediate turn.Compaction is lossy: the summary keeps the gist and quietly drops exact file paths, line numbers, and edge cases the model later needs, so it can re-explore or re-introduce a bug you already fixed. Before you compact, ask Claude to write down the concrete facts (file names, function signatures, decisions) you cannot afford to lose, then paste them back after.

```bash
/compact
```

Use `/compact` mid-task. Use `/clear` between tasks. The difference: `/compact` keeps a summary of the current work in the window; `/clear` wipes the slate entirely so the next task starts from `CLAUDE.md` and nothing else.

## Retrieval over stuffing

When you have a large codebase, do not dump it all into the session. Retrieve only what is relevant.

### Let Claude Code do the retrieval

Claude Code runs `grep`, `find`, and file reads as tool calls. Rather than pre-loading every file, let it search:

Find every place we call `spawnNPC` and list the file paths and line numbers. Do not edit anything yet.

Claude will grep, read only the matching files, and report back. The context stays tight because only the relevant excerpts land in the window.

### When should I guide retrieval vs. let Claude explore?

| Situation | Strategy |
|---|---|
| You know the exact file | @-mention it directly |
| You know the subsystem but not the file | Name the folder; let Claude grep |
| Codebase under 20k tokens total | Let Claude read everything |
| Large codebase, narrow task | @-mention the contract/interface file only |
| Dynamic data (logs, test output) | Paste the relevant excerpt, not the full log |

The goal is the same in every case: put the signal in the window and leave the noise out.

## Practical heuristics

**Measure before optimising.** Claude Code shows token usage and cost after each response. Watch the numbers on long sessions. Surprises are common: a `CLAUDE.md` you thought was concise may be 2,000 tokens once all the referenced conventions are counted.

**Tool definitions cost tokens.** Each MCP server or tool registered in `.claude/settings.json` adds serialised definitions to every turn. Only register tools the current project needs.

```json
{
  "mcpServers": {
    "database": { "command": "npx", "args": ["mcp-server-sqlite", "db.sqlite"] }
  }
}
```

Disable MCP servers you are not actively using. The token overhead is per-turn, not per-session.

**Images are expensive.** A 1024x1024 image costs roughly 1,600 tokens. If Claude only needs to read text from a screenshot, extract the text first and paste that instead.

**Few-shot examples are worth their cost.** Two well-chosen examples of input/output format typically improve output quality more than doubling the length of prose instructions, a technique covered in [few-shot prompting](/guides/few-shot-prompting). Put them in `CLAUDE.md` under a clear heading so they persist across sessions without re-pasting.

**Use /clear between unrelated tasks.** Do not drag auth-system history into a CSS layout task. The stale turns are noise and they cost real money. `/clear` is free.

**CLAUDE.md is the highest-impact token spend.** Every rule in `CLAUDE.md` applies to every turn. Write it carefully. Delete rules that no longer apply. Stale rules are noise that the model still pays attention to.

## How do I check my token count?

Claude Code displays a running token count and cost estimate in the session footer. Use it. Before starting a large task, check where you are. If the count is already high, run `/compact` or `/clear` before adding more.

You can also ask Claude directly:

How many tokens are in the current context window? Give me a rough breakdown by source (CLAUDE.md, files loaded, conversation history).

Claude will estimate the breakdown. This is useful for diagnosing why a session is expensive before you reach the compaction threshold.

Use `/cost` at any point to see the accumulated cost for the current session without interrupting the flow.

## Checklist

Before sending any context, ask:

- Does every section serve the current task?
- Is stable content (CLAUDE.md, rules) kept short and precise?
- Have I @-mentioned only the files this task touches?
- Have I removed conversation turns older than the last few that are still relevant, using `/compact` or `/clear`?
- Am I sending full files, or only the functions the model needs to read or modify?
- If this is a long session, is the history compacted?
- Do I know the rough token count before sending?

A context that passes this checklist costs less, responds faster, and produces more accurate outputs than one assembled by default.
