DEV Community

Fogel
Fogel

Posted on

How to Reduce Claude Code's Initial Context and Avoid Prompt Cache Breaks

Introduction

Lately, discussions around token optimization in Claude Code have focused primarily on skills, external tools, and optimizing CLAUDE.md. However, I noticed there is much less discussion about the massive savings you can achieve simply by configuring Claude Code's built-in settings correctly.

Curious about what the Claude Code harness actually adds behind the scenes, I decided to dive into its settings and environment variables. The results were much more interesting than I expected, which inspired me to write a series of articles on the topic.

In this article, I will break down the components of the Initial Context that Claude Code builds at the beginning of a new session. I'll analyze how many tokens these components consume and whether they dynamically change between sessions (which causes cache invalidation).

The goal of this article isn't to reduce the context to the absolute bare minimum. The goal is to remove data that is not useful for our work with Claude Code while preserving the capabilities we actually need for our workflow.

What is Initial Context?

The Initial Context is the foundational information that Claude Code adds at the beginning of a session. Part of it is sent as a top-level System Prompt within the system array, and another part is added immediately after the first user prompt inside the messages array.

The initial context consists of the following elements:

Inside the tools array:

  • Tools like Write, Read, Artifact, Glob, etc.

Inside the system array:

  • System prompts
  • Memory instructions

Inside the messages array:

  • CLAUDE.md
  • Git instructions
  • Deferred tools list (without schemas)
  • Built-in agents
  • Skills
  • Information from the IDE

The earlier a token appears in the conversation with Claude, the more expensive its cumulative cost becomes. This is because every new prompt we send to the model includes the Initial Context and the entire conversation history. Therefore, since the initial context accompanies us from the very first message, it has the highest cumulative impact on token consumption.

Furthermore, the more irrelevant text you feed into models, the more they tend to lose focus. The context should contain as much relevant information as possible, and as little irrelevant information as possible.

How does Prompt Caching work?

Every time you send a prompt to Claude, the entire context (initial context + conversation history) is sent along with it. Instead of reprocessing the same text over and over again, Claude can read previously processed text from its cache, process only the new text, and write that new text to the cache. This makes responses significantly faster and drastically reduces costs.

This mechanism relies on Prefix Matching: The model reads sequentially from the cache starting from the beginning of the prompt, until it reaches the first change in the text. The moment a single character changes in the middle of the context, all the information following it is no longer read from the cache - it is rewritten to the cache at full price.
Therefore, our goal is to keep the beginning of our context as static as possible and avoid dynamic content.

According to Claude's documentation, reading tokens from the cache costs a fraction of the base input token price. Currently, writing to a 1-hour cache costs 2x the base input token price, while a cache read costs at most 0.1x the base input token price.
For example, with Claude Opus 5, writing to a 1-hour cache costs $10 per million tokens, while reading from it costs only $0.50 per million tokens - a 20x price difference. Furthermore, in Claude Opus 5.5, this gap widens to a massive 40x price difference, and models like Claude Fable 5.1 push this gap to a significant 80x price difference!

Note: If we don't send a prompt to Claude within the defined cache TTL (5 minutes or 1 hour), the cache expires. The next time we send a message, the entire context will be rewritten to the cache from scratch instead of being read from it.

TL;DR

I found that Claude Code adds several components to the initial context that aren't necessarily needed for every task. By applying the configurations detailed in this article, I reduced the Initial Context from 35,011 tokens to 17,862 tokens (a ~49% reduction). Furthermore, the number of tokens forced to be rewritten to the cache in subsequent sessions dropped from 7,333 to 0.

Ultimately, you can decide which of these components are essential for your specific workflow with Claude Code.

Results by Component

Component Added to Context Cache Invalidation Risk
Artifact 11,403 tokens Always breaks the cache
Git instructions ~500 tokens Very High
Auto memory 738 tokens + MEMORY.md content High
Skills ~2,100 tokens Low
Claude Docs MCP ~1,701 tokens None
IDE Integration ~100 tokens (manually removable) None

Bonus: I also discovered how Claude Code's payload ordering breaks the cache on the very first prompt, and how starting every session with a generic "Hi" can save you ~65% on your initial prompt costs.

How were the tests performed?

To truly understand what Claude Code adds to the context, I intercepted and analyzed the network traffic of the API requests Claude Code makes when sending a message.
I mapped the tools, system, and messages arrays in the payload against the available configurations in settings.json and environment variables. For every overlapping setting, I compared the API request before and after the change, comparing both content and token count.

How did I measure the number of tokens?

I used two methods:

  1. The /context command: Behind the scenes, this command triggers several API calls to count the number of input tokens for different parts of the system prompt and tools.
  2. A Regular Prompt: I also sent a simple prompt ("hi") to trigger a full-context API call. The API response indicates exactly how many tokens were read from the cache and how many were written to it. In addition, I compared the context text sent before and after each configuration change to understand the specific setting's contribution to the session's context.

Test Environment

The tests presented in this article were performed using:

  • Claude Code version 2.1.278.
  • Model: Claude Opus 5 (unless otherwise specified).
  • A Claude subscription which, according to Claude Code documentation, utilizes a one-hour TTL cache.

Note: These results were measured in this specific environment. Initial context structure, token counts, and caching behavior may vary across Claude Code versions and models.
Also note that according to Claude's documentation, models from version 4.7 and above use a different tokenizer and consume up to 30% more tokens. Therefore, for Claude 4.7 and above, the quantitative token savings will be even more significant.


Deep Dive by Component

1. Artifact

Artifacts allow us to generate and share web pages via a private URL on claude.ai. For my own use cases, I don't need this feature, so I decided to test its impact on the Initial Context. It is enabled by default.

What does it add to the context?

Comparing the context with Artifact enabled vs. disabled revealed:

  1. The Scratchpad Directory path is added to the system prompt in the messages array (222 tokens).
  2. Artifact-specific skills and descriptions are added (which can also be viewed using /context all)
    1. design (340 tokens)
    2. artifact-design (70 tokens)
    3. artifact-diagramming (70 tokens)
    4. artifact-capabilities (220 tokens)
  3. An Artifact tool is added (10,481 tokens). Total addition: 11,403 tokens.

Impact on Prompt Caching

The Scratchpad Directory path added to the system prompt in the messages array contains a unique Session ID. Because this ID changes between sessions, it alters the system prompt and guarantees a cache miss.

Therefore, I decided to measure the impact of that cache miss on the number of tokens that had to be written to the cache instead of read from it.

To prove this, I compared cache writes across four new, clean sessions, sending identical prompts:

  1. Artifact Enabled: All tokens (34,724) were written to the cache (initial run).
  2. Artifact Enabled: The system prompt changed because the directory name changed in the new session, breaking the prefix matching. 7,333 tokens were rewritten to the cache.
  3. Artifact Disabled: The system prompt changed because the Artifact tool and Scratchpad Directory text were removed, causing a cache miss. 22,972 tokens were rewritten.
  4. Artifact Disabled: The system prompt remained completely static, so there was no cache miss. 0 tokens were rewritten, everything was read from the cache.

Summary of disabling Artifact:

  • Saves 11,403 tokens on every single prompt.
  • Prevents guaranteed cache misses between sessions caused by content that changes in the system prompt. Converting a 7,333-token write into a read is particularly significant (remember the 20x to 80x price difference).

How to disable:

Add "enableArtifact": false to your global or project settings.json, or set the environment variable: CLAUDE_CODE_DISABLE_ARTIFACT=1.

2. Git Instructions

When working inside a Git repository, Claude Code adds your current Git status and recent commits into the system prompt in the messages array. This is enabled by default.

What does it add to the context?

I compared the context with Git instructions enabled vs. disabled.
It adds approximately 500 tokens to the system prompt.

Impact on Prompt Caching

Because the status of files in your working directory and your recent commits change frequently, this introduces a high risk of cache misses. I tested this by creating a new file and starting a new session - this caused 6,415 tokens to be rewritten to the cache.

Trade-offs

If disabled, Claude won't automatically know what branch you are on or what the current Git status is, unless it explicitly runs a git command to check.

My Recommendation

Since this is highly dynamic information and Claude Code can easily retrieve it using terminal commands when needed, it is better to avoid including it in the system prompt.

How to disable:

Add "includeGitInstructions": false to settings.json, either globally or at the project level. Another option is to set: CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1.

3. Auto Memory

Auto memory allows Claude to accumulate knowledge across sessions automatically without requiring manual input. It is enabled by default.

What does it add to the context?

  1. Instructions for managing memory located in the system prompt (~738 tokens).
  2. The actual content of the MEMORY.md file (Claude loads up to the first 200 lines or 25K, whichever comes first). Therefore, the actual number of tokens added by this component varies.

Impact on Prompt Caching

Because MEMORY.md gets updated, changes to this file between sessions will break the cache.

Ongoing Token Consumption During the Conversation

In addition, the act of Claude Code updating the auto-memory contents (MEMORY.md) during a conversation consumes additional tokens beyond those required to load the context.

Summary of disabling Auto Memory:

  • Saves 738 tokens from the system prompt.
  • Saves the tokens required for the first 200 lines or first 25K of MEMORY.md, whichever comes first.
  • Prevents cache invalidation caused by changes to MEMORY.md.
  • Prevents logical conflicts between Auto Memory and other information in the context, such as CLAUDE.md or our conversation history.

How to disable:

You can disable auto memory using /memory, or add "autoMemoryEnabled": false to the global settings.json, or set CLAUDE_CODE_DISABLE_AUTO_MEMORY=1.
See the Claude Code memory documentation

4. Skills

Disabling Skill Auto-Invocation

When a new skill is added, its name and description are added to the context. A skill can be triggered in two ways:

  1. Claude decides to use it based on its description (Auto-invocation).
  2. The user explicitly invokes the skill using /skill-name.

You can disable auto-invocation (the first way). If you do, the skill's description is removed from the initial context, saving tokens, but you will have to call it manually using /skill-name.

Here are several ways to disable auto-invocation:

  • Specific skill: Add disable-model-invocation: true to the skill's frontmatter.
  • All project skills: Use the skillOverrides setting. Use it for skills whose SKILL.md you don’t want to edit, like skills you didn't write yourself. (Note: this doesn't affect plugin skills. Plugin skills must be managed using /plugin).
  • All skills (including plugins): A clever workaround to prevent auto-invocation for all skills, including plugin skills, is using the setting "skillListingMaxDescChars": 1. This truncates all descriptions, saving at least ~2,000 tokens when including the built-in skills.

Disabling Built-in Skills

Claude Code includes several built-in skills (like keybindings-help or claude-api) that you might rarely use.
The full list of built-in skills can be viewed using: /context all.

  • Context addition: Names and descriptions of bundled skills add about 2,134 tokens.
  • How to disable: Add "disableBundledSkills": true to settings.json. (Note: This completely removes them, meaning you cannot invoke them manually either).

5. Claude Docs MCP

This is a connector that links to Claude Docs on claude.ai. It allows Claude to create, read, edit, comment on, and export documents stored in your claude.ai account. They're not files in your repository.

What does it add to the context?

  1. Instructions on how to use its tools and resources, located in the system prompt in the messages array (~1,031 tokens).
  2. The MCP tools of Claude Docs are loaded (which can also be viewed using /context all)
    1. mcp__claude_ai_Claude_Docs__batch (163 tokens)
    2. mcp__claude_ai_Claude_Docs__guide (212 tokens)
    3. mcp__claude_ai_Claude_Docs__update (295 tokens)

It adds approximately 1,701 tokens to the context.

Impact on Prompt Caching

It doesn't affect prompt caching.

My Recommendation

Since I don't see a reason to use this within Claude Code, I prefer to disable it.

How to disable

  1. Run /mcp, select "claude.ai Claude Docs" and disable it.
  2. Alternatively, remove or disconnect the connector in your claude.ai settings under Connectors. That affects every client using your account, not just Claude Code.

I'd recommend disabling it via /mcp if you only want to turn it off for Claude Code.

6. IDE Integration

If you run Claude Code inside an IDE terminal (like VS Code), it automatically connects to the IDE.
Personally, I often have a file open in the IDE (sometimes with text selected) that is completely unrelated to what I'm asking Claude to do in the terminal.
In that situation, the IDE adds the text [⧉ In filename.ext] or [⧉ X lines selected] to the beginning of the terminal prompt line, even though it may not be relevant to the current conversation.
This increases token consumption, can reduce the model's focus, and may even lead to incorrect answers.
You can easily remove it with backspace, just as you would with any other part of the prompt.

What does it add to the context?

  1. The name of the currently active file in the IDE (Adds ~100 tokens). You can remove it manually from the prompt.
  2. Currently selected lines of the open file in the IDE (Adds a dynamic token count).
  3. Errors showing in the IDE's "Problems" tab (Adds dynamic token count).

Impact on Prompt Caching

Because it is added to the end of the context, it doesn't affect prompt caching.

My Recommendation

I personally prefer that Claude does not automatically consider whichever file happens to be open in my IDE, so I disable the "Attach Open File" setting.

How to disable:

You can prevent Claude Code from adding the currently open file in the editor by disabling the Attach Open File setting in your VSCode settings. When disabled, only the text you actively select is added.

You can also open VS Code settings (Cmd+, on Mac or Ctrl+, on Windows/Linux), go to Extensions -> Claude Code, and uncheck Attach Open File.


Extra Insight: The First Prompt Cache Trap

While analyzing the API payloads, I noticed something interesting: there is a specific System Prompt block that is not sent as part of the system array. Instead, it is added to the messages array immediately after the user's first prompt.

This added System Prompt block contains:

  • Claude Code CLI Environment
  • The deferred tools list
  • Built-in agents
  • Skills list
  • IDE integration data

Because Prompt Caching relies on Prefix Matching (matching from the start of the text until the first change), sending a different first prompt in a new session breaks the sequence immediately.
As a result, that entire massive system block added after your first prompt is treated as "new" text and is written to the cache at the 20x to 80x price!

I tested two sequential sessions (with Artifact disabled, as it always breaks prompt caching):

Scenario Cache Read Cache Write
Two sessions with the same first prompt 23,978 tokens 0 tokens
Two sessions with a different first prompt 17,566 tokens 6,412 tokens

As you can see, changing your first prompt causes Claude to rewrite 6,412 tokens of the system prompt to the cache.

The Practical Workaround: The Static "Hi"

To prevent this cache break, I tested a workflow where I open every new session with a static prompt (e.g., "Hi"). Once Claude responds, I send my actual prompt.

I compared the costs of asking "What model are you using?" in two scenarios:

Scenario A: Sending the question (actual prompt) directly as the first prompt

Action Cache Read Cache Write Total Cost
Prompt 1: "What model are you using?" 17,566 6,416 $0.072943

Scenario B: Starting with a Fixed First Prompt ("Hi"), then asking the question (actual prompt)

Action Cache Read Cache Write Total Cost
Prompt 1: "Hi" 23,978 0 $0.011989
Prompt 2: "What model are you using?" 23,978 146 $0.013449
Total 47,956 146 $0.025438

Conclusion:
Even though Scenario B required two API calls and processed double the total tokens, the overall cost dropped by 65%. We successfully converted an expensive cache write into a cheap cache read.

Note: This workaround only saves money if you are starting a new session within 1 hour of your previous prompt. If your cache has completely expired, you will pay for a full rewrite regardless, so you might as well send your actual prompt first (in our example: "What model are you using?").


Conclusion

The goal of this optimization is to achieve a context window that only contains data actively contributing to the current session, while keeping that data as static as possible to maximize prompt caching.

By understanding the API payload structure and tweaking Claude Code's settings, we achieved four major goals:

  1. Token savings: Reduced the initial context from 35,011 to 17,862 tokens, a 49% drop.
  2. Prompt cache stability: Eliminated dynamic text in the initial context (like the Scratchpad path) that breaks prefix matching and causes cache misses, dropping token rewrites from 7,333 to 0.
  3. Model focus: Removed irrelevant background information (like randomly opened IDE files), allowing Claude to focus entirely on the actual prompt.
  4. Workaround for the first prompt cache trap: Understanding that a system prompt block containing skills and other metadata is inserted after the first user prompt inside the messages array allows us to use a fixed opening prompt (such as "Hi"). This saves approximately 65% on the cost of the initial prompt in sessions where the previous session occurred within the last hour.

Every developer should decide which of these components are worth their token cost.

Here is a summary of the settings discussed in this article:

// ~/.claude/settings.json or .claude/settings.json in your project
{
  "env": {
    "CLAUDE_CODE_DISABLE_ARTIFACT": "1",
    "CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS": "1",
    "CLAUDE_CODE_DISABLE_AUTO_MEMORY": "1"
  },
  "disableBundledSkills": true,
  "skillListingMaxDescChars": 1
}
Enter fullscreen mode Exit fullscreen mode

Disabling Claude Docs MCP: Run /mcp, select "claude.ai Claude Docs" and disable it.

In the next article, we will focus on workflows and configurations to save tokens during active, ongoing conversations, rather than just the initial context. Stay tuned!

Top comments (0)