Spotify's Portal cuts Claude Code token use by 90%

Spotify's Portal cuts Claude Code token use by 90%

A post on Spotify's engineering blog describes a Claude Code plugin called shunt that routes I/O heavy coding work away from Claude to a cheaper model, cutting the author's Claude Code token usage by 90%. The starting observation: most of what a coding agent does is not reasoning but I/O, reading several files to answer one question, generating a test file that copies the pattern of twenty neighbors, updating docs after a meeting, and all of it runs through a frontier model that is overqualified for the task. The post cites a market context for that cost: a quarter of engineering leaders already spend $200 to $500 per developer per month on AI coding tokens, some past $2,000, and AI coding costs are expected to exceed the average developer's salary by 2028. The fix runs on Portal by Spotify's AiKA Modes, described as declarative agents that run on an ephemeral, serverless-style runtime: you set the instructions, pick a model, set parameters such as temperature, attach MCP tools, and Portal runs it, with no infrastructure, API keys or long-running servers to manage. The author built two modes, both using Gemini 2.5 Flash as the worker model: bulk-reader, which reads a set of files and answers a question in structured bullets with no prose, and code-writer, which generates code such as tests or config stubs that match the style of a supplied reference file, outputting only code with no markdown fences. Both modes are public inside Portal. The first version of the routing was just a block of rules in CLAUDE.md, which the author calls advisory and easy for Claude to ignore, and which had to be copied into every project. The current version, the shunt plugin, enforces the routing in three layers. Layer one is two Claude Code PreToolUse hooks: check-file-size blocks a Read call once a file exceeds a configurable line threshold, default 350 lines (an example in the post sets it to 500 via the SHUNT_MIN_LINES setting), and redirects Claude to the bulk-reader mode, while targeted reads pass through; check-bash-read applies the same logic to cat, head, tail, less and more, letting piped commands such as cat file | grep through as targeted reads. Layer two is two bash scripts that wrap Portal CLI calls: bulk-read wraps each file in XML tags and sends them with the question to bulk-reader, and each call is described as ephemeral, with nothing stored server side, so re-sending files on a follow-up question costs nothing extra because the file corpus never enters Claude's own context; code-write sends a spec and a required reference file to code-writer, strips markdown fences from the result, and can write the output straight to disk without Claude ever seeing the generated code. Layer three is two skill files that tell Claude when and how to invoke the scripts, so the system still works, just less smoothly, even if Claude skips the skill description, because the hooks block expensive reads regardless. Modes are resolved by name, preferring a user's own mode, then their team's, then the public one, so forking bulk-reader into a customized version takes precedence automatically. Testing this against a Java monorepo across four scenarios, the author reports mean bulk-read token savings of around 90%; the code-write case is described as harder to measure in tokens because without shunt Claude both reads the reference files and produces the code as expensive output tokens, whereas with shunt the code goes straight to disk. The post also states clear limits: editing cannot be delegated because the worker model's summaries lack reliable line numbers, so Claude still reads the specific section directly when it needs to edit; reasoning cannot be delegated either, since the worker model caught only surface level patterns and missed a subtle thread-safety bug in testing that Claude found once given the right context, so the routing explicitly excludes debugging, architectural decisions and safety-critical code; and latency adds up, since each delegation is a network round trip from Claude Code to the Portal backend to the worker model and back, typically taking 10 to 30 seconds, with Portal capping a single invocation at 30 seconds, which is why the line threshold exists to keep small reads from being routed. The author frames the modes, not the plugin, as the reusable, shareable and composable part: the same bulk-reader and code-writer work across any project or tool that can call the Portal CLI, are public so others can use them without recreating them, and could be joined by similar modes for documentation, code review or translation, with the routing plugin unaware of which model or prompt sits behind a given mode. To try it, the post points to installing the portal and shunt plugins from the spotify/portal-ai-plugins marketplace and running /portal:setup in a Claude Code session to authenticate against a Portal instance.

Key facts

  • shunt is a Claude Code plugin, described in a Spotify engineering blog post, that routes bulk file reads and boilerplate code generation to Gemini 2.5 Flash via Spotify's Portal AiKA Modes, cutting the author's Claude Code token usage by 90%.
  • Two public Portal modes do the work: bulk-reader answers questions over multiple files in structured bullets, and code-writer generates code matching a required reference file's style, both running on Gemini 2.5 Flash at temperature 0.2.
  • Enforcement runs through PreToolUse hooks that block a Read call once a file passes a default 350-line threshold (configurable via SHUNT_MIN_LINES) and redirect to bulk-reader, plus two wrapper scripts and skill files that tell Claude how to call them.
  • Benchmarked across four scenarios on a Java monorepo, mean bulk-read token savings ran around 90%; the author says delegation cannot cover editing (no reliable line numbers from the worker) or reasoning (the worker missed a thread-safety bug Claude caught).
  • Each delegation is a network round trip through the Portal backend typically taking 10 to 30 seconds, with a hard 30-second cap per invocation, which is the stated reason small reads are not worth routing.

Why it matters

The post's framing is that most of what a coding agent spends tokens on is not reasoning at all, it is I/O: reading files to answer a narrow question, writing boilerplate that already has twenty local examples to copy, updating docs. All of that runs through a frontier model priced and built for hard reasoning. The post cites a cost backdrop for that mismatch: a quarter of engineering leaders already spend $200 to $500 per developer per month on AI coding tokens, some past $2,000, and AI coding costs are expected to exceed the average developer's salary by 2028. The proposed fix is a routing pattern, not a bigger model or a cheaper seat license: split the work by whether it needs judgment, and send the rest to a smaller, cheaper worker model.

Who it affects

Directly, engineering teams already running Claude Code at scale who are watching per-developer token spend climb, and any team building on Spotify's Portal/AiKA platform who can reuse the public bulk-reader and code-writer modes as-is. More broadly, it speaks to platform and tooling teams evaluating model-routing setups for coding agents in general, since the pattern (cheap worker model for I/O, expensive model reserved for judgment) does not depend on Portal specifically.

How to use it

The setup requires access to a Portal instance. From there, install the portal and shunt plugins from the spotify/portal-ai-plugins marketplace (claude plugin marketplace add spotify/portal-ai-plugins, then claude plugin install portal@portal and claude plugin install shunt@portal), then run /portal:setup in a Claude Code session to authenticate the Portal CLI. The bulk-reader and code-writer modes are already public, so no mode setup is needed to start; asking a question that spans multiple files is enough to trigger the routing. Customizing a mode (a different worker model or different instructions) means forking it in Portal, after which the forked version takes precedence automatically. The block threshold for reads is configurable via the SHUNT_MIN_LINES environment variable, shown set to 500 in .claude/settings.json against a stated default of 350.

How solid is it

This is a first-person account on Spotify's own engineering blog, with code, configuration and hook logic shown in enough detail to reproduce the setup, plus a stated benchmark (four scenarios on a Java monorepo, mean bulk-read savings around 90%) rather than an unsupported claim. What is missing: no scenario-by-scenario numbers, sample size or file sizes are given for that benchmark, and no source or methodology backs the $200 to $500 and $2,000 spend figures or the 2028 cost-crossover claim. The post also does not name its author, give any title, or state any pricing for Portal, AiKA or Gemini 2.5 Flash usage against Claude's, so cost comparisons rest on the token-count savings alone, not a dollar comparison.

Risks and caveats

The author states explicit limits on what this can safely delegate. Editing cannot be routed, because the worker model's summaries do not carry reliable line numbers, so Claude still has to read the exact section itself before making a change. Reasoning cannot be routed either: in the author's own testing the worker model found only surface-level patterns and missed a subtle thread-safety bug that Claude caught once given the right context, so the routing explicitly excludes debugging, architectural decisions and safety-critical code. Latency is a real cost, not a rounding error: each delegated call is a network round trip through the Portal backend to the worker model and back, typically 10 to 30 seconds, with Portal capping any single invocation at 30 seconds, so very large generations need to be split, and small reads are not worth delegating at all, which is the reason the line threshold exists in the first place.

“Most of what an AI coding agent does for me isn't thinking. It's I/O.”

— the post's author, on Spotify's engineering blog