[BUG] Image Inputs via Read Tool or @ Reference Consume 7–10× More Tokens with On-Prem LLMs
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When Claude Code reads a local PNG/JPEG image using the Read tool, or when I reference an image using @, it consumes an unexpectedly large number of input tokens.
For the same ~2K-resolution image, I consistently observe approximately:
- Read tool /
@image reference: ~100k–150k tokens - Copying and pasting the same image directly into the prompt: ~14k tokens
This means the same image can consume roughly 7–10× more tokens depending only on how it is provided to Claude Code.
The issue is reproducible with both PNG and JPEG images.
My environment is:
- Claude Code:
2.1.227 - LLM backend: on-premise LLM
- Network: fully air-gapped / offline
Because of security requirements, the machine cannot access the Internet, so all Claude Code requests are routed to an on-premise LLM backend.
I understand that this differs from using Anthropic-hosted models. However, the large discrepancy appears to depend on the image ingestion path inside Claude Code, because the LLM backend and the image itself remain unchanged between tests.
A similar behavior has also been independently investigated here:
https://cloud.tencent.com/developer/article/2721917
That investigation reports a similarly large difference in token consumption between images read from files and images provided directly to Claude Code.
What Should Happen?
The token cost for processing the same image should be reasonably consistent regardless of whether the image is:
- read from a local file by Claude Code,
- referenced using
@, or - pasted directly into the prompt.
Some difference in overhead between these input methods would be understandable, but a difference of approximately 100k–150k tokens versus ~14k tokens seems excessive.
Ideally, images loaded through the Read tool or @ references should use an image representation that is similarly token-efficient to directly pasted images.
If these input methods intentionally use different image representations or preprocessing pipelines, it would also be helpful to document this behavior, especially for users integrating Claude Code with custom or on-premise multimodal LLM backends.
Error Messages/Logs
Steps to Reproduce
- Run Claude Code.
- Configure Claude Code to use a multimodal LLM backend.
In my case, this is an on-premise LLM running in a fully air-gapped environment.
- Prepare a PNG or JPEG image with approximately 2K resolution.
For example:
``text``
test-image.png
- Ask Claude Code to inspect the local image file and allow it to use the Read tool.
For example:
``text``
Please inspect test-image.png and describe what you see.
- Observe the token usage after Claude Code reads the image.
In my environment, a single ~2K image consumes approximately:
``text``
100k–150k tokens
- Start a fresh context/session and reference the same image explicitly using
@.
For example:
``text``
Please analyze @test-image.png and describe what you see.
- Observe the token usage.
I see similarly high token consumption with the @ reference path.
- Start another fresh context/session.
- Copy the exact same image to the clipboard and paste it directly into the Claude Code prompt instead of referencing the file.
- Ask the same question:
Please analyze this image and describe what you see.
- Observe the token usage.
In my environment, the directly pasted image consumes only approximately:
14k tokens
- Compare the results:
Read tool / @ reference: ~100k–150k tokens
Direct image paste: ~14k tokens
The image, model backend, and task are otherwise the same. The primary variable is how the image is supplied to Claude Code.
Claude Model
Other
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.227 (Claude Code)
Platform
Other
Operating System
Other Linux
Terminal/Shell
Xterm
Additional Information
_No response_
3 Comments
Thanks for the detailed report. I tried to reproduce this on Claude Code 2.1.233 by capturing exactly what the CLI sends to the API for the same 2048x1536 PNG (~920 KB) via three routes: the Read tool, an
@file reference, and an image supplied directly in the user message (the paste path).In all three cases Claude Code sent the identical image bytes: it was downscaled/recompressed to a ~470 KB JPEG (base64 length 625,300) in every case. The only difference is where the block sits in the request: Read and
@deliver the image inside atool_resultcontent block, while a pasted image is a top-level image block in the user message. Against the Anthropic API both positions are tokenized the same way (vision tokens based on pixel dimensions, roughly width x height / 750 - see https://docs.anthropic.com/en/docs/build-with-claude/vision), so a 2K image costs on the order of a few thousand tokens either way, never 100k+.So the 7-10x gap you see is coming from how your on-premise backend (or the proxy in front of it) tokenizes an image block nested inside
tool_resultcontent - it looks like it is treating it as text (base64) rather than as an image. That is outside what Claude Code controls; the client-side image processing is the same for both paths.If you can share what your backend/proxy reports for a request containing an image inside a
tool_resultblock vs. a top-level user image block, that would confirm it. If you can show the same gap against the Anthropic API directly, please reopen with theclaude doctoroutput and steps.🤖 Generated with Claude Code
Hi @bcherny, thanks for the reply.
Let me correct my earlier wording — this isn't specifically an on-prem LLM issue. The real pattern is that any non-Anthropic model sees a massive token-usage spike when an image is loaded via
@or the Read tool.The Tencent community post I originally referenced ran a cross-validation experiment that included both an Anthropic-official model and a range of non-Anthropic LLMs. Here's the full list of models tested:
claude-haiku-4.5gpt-5.6-lunadoubao-seed-2-1-turbo-260628step-3.7-flashmimo-v2.5kimi-k3qwen3.7-plusgrok-4.5gemini-3.5-flashMiniMax-M3Results:
claude-haiku-4.5— the only Anthropic-official model in the set — used the Read tool normally. All 9 non-Anthropic models, however, saw token usage jump to roughly 400k–500k tokens for the same image via the Read tool, up to ~250x the ~2k-token baseline, and a few errored out entirely. Pasting/dragging the same image directly into the prompt brought every one of those 9 models back down to normal.So the split here isn't "on-prem vs. cloud" — it's "Anthropic-official model vs. everything else," which points at the image-ingestion path behind Read/
@rather than at any specific deployment setup.@bcherny Are there any updates? Or is there any additional information I need to provide? Thank you.
Additionally, I found that when used with third-party LLMs, Read/@ image not only consumes an abnormally large number of tokens but also fails to read the image correctly, without displaying any errors or warnings.
The same issues occurs on both Linux and Windows with the latest version of Claude Code (v2.1.235).