Opus or Sonnet in Claude Code? Model routing, effort and the prompt cache

Updated

A cheaper model does not always mean fewer tokens used. In Claude Code, the prompt cache decides most of the bill, and the cache has rules that a naive model switch breaks.

List prices per million tokens

ModelInputOutputCache read
Claude Opus 5.5$4$20$0.20
Claude Opus 5$5$25$0.50
Claude Sonnet 5$2$10$0.20
Claude Haiku 4.5$1$5$0.10

Cache reads on Opus 5.5 and Sonnet 5 cost the same. When most of your spend is cache reads, as it is for long agent sessions, moving to Sonnet saves only on output, fresh input and cache writes.

The cache belongs to one model

A cached prefix is only valid for the model that wrote it. Switch models in the middle of a chat and the next call writes the whole context to cache again, at 1.25x or 2x the input price. A router that flips models per request can cost more than no router.

Why “route down” breaks in Claude Code

Claude Code shapes each request for the model it thinks it is calling. In our tests with Claude Code 2.1.280, an Opus-shaped request sent to Sonnet was rejected with a 400 error (for example, per-turn effort is not supported on that model). A Sonnet-shaped request sent to Opus works.

Effort is the bigger lever

Effort (low to max) controls how much the model thinks before it answers. Lower effort means fewer and more consolidated tool calls and shorter replies. Set it with /effort or the effortLevel setting. On most models an effort change also invalidates the cache, so treat it like a model choice: set it at the start of a chat.

More guides