Portal by Spotify Cut Claude Code Token Usage by 90%
- title
- Portal by Spotify Cut Claude Code Token Usage by 90%
- type
- summary
- summary
- Spotify PM routes Claude Code's bulk file reads and boilerplate to a cheaper model via hooks; the 90% covers bulk reads, not total usage
- tags
- claude-code, cost, model-routing, agentic-coding
- created
- 2026-09-13
- updated
- 2026-09-13
Dimitri Mazmanov, a principal product manager at Spotify, starts from the observation that most of what a coding agent does is I/O rather than thinking: reading five files to answer a question about one method, writing a test that copies the twenty tests beside it. His setup sends that work from claude-code to a cheaper model and keeps the frontier model for reasoning. It is a product post for Portal, Spotify's commercial Backstage offering, and the routing layer only works against a Portal instance. The mechanism is still worth recording apart from the product.
The cost framing he opens with is borrowed: a Gartner forecast that AI coding costs will pass the average developer salary by 2028, and reports of engineering leaders spending $200 to $500, sometimes more than $2,000, per developer per month on tokens.
Modes
Portal's AiKA Modes are declarative agents on an ephemeral runtime: instructions, a model, parameters like temperature, and optional MCP tools, callable from the Portal CLI or API. He defines two, both on Gemini 2.5 Flash at temperature 0.2 in his examples. bulk-reader reads files and answers a question in terse structured bullets. code-writer produces files from a spec and a reference file, matching its conventions, with output restricted to code. That restriction matters, he notes, because otherwise the worker wraps everything in markdown fences and prose that Claude then has to read through.
Routing, three layers
The first attempt was routing rules in CLAUDE.md. Claude followed them sometimes. They were advisory, easy to ignore, and had to be copied into every project.
The current version is a Claude Code plugin called shunt. Its first layer is two PreToolUse hooks. check-file-size blocks any Read of a file longer than a threshold (350 lines by default, set with SHUNT_MIN_LINES) and tells Claude to use the bulk-reader skill instead; reads with an offset and limit pass, on the grounds that Claude already knows which part it needs. check-bash-read does the same for cat, head, tail, less and more on large files, letting piped commands through.
{
"env": {
"SHUNT_MIN_LINES": "500"
}
}
The second layer is two shell scripts wrapping the Portal CLI. bulk-read wraps each file in XML tags and sends them with the question; the files go to the worker and never enter Claude's context, so re-sending them for a follow-up costs Claude nothing. code-write sends a spec and a required reference file, strips fences from the output and can write straight to disk, so Claude never sees the generated code at all.
bulk-read --question "Which methods call the database?" --paths src/Service.java src/Handler.java
code-write --spec "Write tests for UserService" --reference tests/OrderTest.java --target tests/UserTest.java
The third layer is two skill files telling Claude when and how to call the scripts. The layering is what he means by degrading gracefully: if Claude ignores the skill, the hook still blocks the expensive read.
The 90%
The measurement is a Java monorepo, four scenarios, comparing the tokens Claude would spend reading files directly with the tokens of the bulk-reader's summary. Mean savings on bulk reads were about 90%. No per-scenario numbers are published, nothing measures whether the answers built on the summaries were as good, and the headline's "cut my Claude Code token usage by 90%" is a stronger claim than "bulk reads cost about 90% less", which is what the body supports. Code-write savings he calls harder to measure and does not quantify.
What he says does not work
Editing cannot be delegated, because the worker's summaries do not carry reliable line numbers; Claude still reads the section it edits, which is why targeted reads pass the hook. Reasoning cannot be delegated either: in his testing the worker found surface patterns and missed a thread-safety bug Claude spotted in seconds, so debugging, architecture and safety-critical code are excluded from routing. And every delegation is a network round-trip of 10 to 30 seconds, with Portal capping an invocation at 30 seconds, so small reads cost more than they save. That is what the line threshold is for.
Two costs he does not raise. When code-write puts files on disk that Claude never reads, nothing in the loop has reviewed them; they land with less scrutiny than code the main agent wrote. And a bulk-reader summary becomes ground truth for Claude's next step, so the cheaper model's misreadings travel into decisions without a signal that they came from a different model. His own thread-safety example is that failure caught once.
Related
The principle is the one in code-mode-token-savings: data that never enters the transcript is never paid for and never crowds the window. Shunt applies it to file contents rather than tool results. The routing is task-shaped rather than request-shaped, which separates it from llm-api-routing-layer gateways and from claude-code-router, whose per-request slots send whole requests to other providers. Unlike a /model switch, delegation leaves Claude's own session and its prompt cache intact, since the worker runs as a separate call. The move from CLAUDE.md rules to hooks, from advice to enforcement, is the same one mcp-vs-skills circles: a skill tells the agent what it could do, a hook decides what it may. local-ai-is-not-opus reached the matching conclusion from the other direction, with a cheaper local model handling bounded reads well and failing on long-horizon work, and ai-token-budget-explosion is the enterprise spending problem this post is selling a fix for.