---
title: "Spotify shunt Review: Setup, Savings and Limits"
canonical: https://wavect.io/blog/spotify-shunt-claude-code-token-routing/
language: en
description: "Review Spotify shunt's Claude Code token routing: Portal requirements, the 90% benchmark, hook limits, worker costs and a measured rollout for engineering teams."
image: "https://wavect.io/img/blog/headers/header_spotify-shunt-claude-code-token-routing.png"
---

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

10 min read · 12 Sep 2026 Last reviewed September 12, 2026

[**Next**](/blog/smarter-token-usage-with-your-ai-coding-agent/)

# Spotify shunt Review: Claude Code Token Savings, Setup and Limits

TL;DR

Spotify shunt routes large file reads and predictable code generation through Portal AiKA worker modes. Its reported 90% saving concerns estimated Claude read-context tokens in selected bulk-read scenarios, not the combined bill. You need an authenticated Portal instance with AiKA, accessible modes and a configured model. Read hooks enforce supported routing; code-writer remains skill-guided. Compare worker costs, caching, latency and verification before adopting it.

**Spotify shunt is worth testing when Claude Code repeatedly opens large files to answer narrow questions. It is not evidence that your entire AI coding bill will fall by 90%.** The useful decision is whether a cheaper reader can return enough accurate context to complete the task without creating extra verification work.

[Spotify's engineering article](https://engineering.atspotify.com/2026/9/portal-by-spotify-cut-my-claude-code-token-usage-by-90) describes two Portal AiKA modes: `bulk-reader` for focused answers over files and `code-writer` for predictable generation from an existing example. Its examples use Gemini 2.5 Flash at temperature 0.2. Those are configurable worker choices, not a requirement to replace Claude as the main coding agent.

This is a source-based review, checked on 12 September 2026, not a Wavect production benchmark. It concerns **shunt in `spotify/portal-ai-plugins`**, not another project with the same name. The broader [coding-agent token-cost playbook](/blog/smarter-token-usage-with-your-ai-coding-agent/) covers caching, batching and general cost control. Here, the question is narrower: when does Spotify's file-I/O delegation actually pay off?

**Independence and trademarks:** Wavect publishes this page and is itself a provider, so we have a commercial interest in it. We are not affiliated with, endorsed by or partnered with the other companies named here, and all third-party company names, brands and trademarks are the property of their respective owners. Statements about other providers are taken from publicly available sources, primarily their own published pages, as of the review date shown on this page, and may have changed since. Please verify them directly before you decide. This page was written to the best of our knowledge and with the intent to remain objective. If you believe anything here is inaccurate or unfair, write to us and we will correct it: [office@wavect.io](mailto:office@wavect.io)

## What did the reported 90% saving measure?

Start with the denominator. The public [benchmark specification](https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/evals/benchmarks.json) describes Claude-context token savings and estimates code tokens as **characters divided by four**. This is an approximation, not a provider billing ledger. Its included TypeScript fixtures are also not the Java monorepo described in the published results, so running the fixture harness is not an exact reproduction of that experiment.

The [shunt README](https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/README.md) reports these results from a 162,000-line Java monorepo:

| Published scenario | Lines read | Without shunt | With shunt | Publisher-reported saving |
| --- | --- | --- | --- | --- |
| One large file | 4,014 | 33,684 tokens | 5,737 tokens | 82% |
| Source file and tests | 7,408 | 75,990 tokens | 4,148 tokens | 94% |
| Files across services | 1,281 | 16,221 tokens | 821 tokens | 94% |

The README reports a 90% mean. Its separate code-writing row describes 833 lines written to disk, but gives no comparable percentage. **Neither the table nor that mean establishes a 90% reduction in combined Claude, worker, platform and engineering costs.** The rows above retain the publisher's percentages rather than presenting them as independently remeasured figures.

For example, consider an explicitly hypothetical read: Claude previously received 40,000 tokens; a worker now consumes those 40,000, produces a 4,000-token summary, and Claude receives that summary. Claude's read context shrinks 90%, while total tokens across the two models are 48,000 before other overhead. Different token prices can still make this cheaper. Token reduction and bill reduction are different measurements.

## Why a hook changes what CLAUDE.md cannot guarantee

A repository instruction asks an agent to behave a certain way. A tool hook can intervene before a matching tool call runs. Anthropic's [hook reference](https://code.claude.com/docs/en/hooks) documents that distinction through `PreToolUse` decision control.

Spotify's [Read-hook implementation](https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/hooks/check-file-size) checks the requested file's line count. Its default threshold is 350 lines, adjustable through `SHUNT_MIN_LINES`; an unrestricted read of a larger file is redirected toward bulk-reader. Reads with an explicit offset or limit pass through, allowing Claude to inspect the exact section needed for an edit. At the default threshold, a 350-line file is not above the limit.

The three layers have different jobs:

| Layer | Responsibility | What it does not establish |
| --- | --- | --- |
| Hooks | Intercept supported broad reads and request delegation | Universal enforcement across every possible tool or data path |
| Wrapper scripts | Send the task and files through Portal and handle the response | Whether the answer is complete or correct |
| Skills | Explain when and how to invoke the workers | A mandatory decision for every generation task |

The README explicitly says **code-writer has no hook enforcement**. Its use remains skill-guided. Treat shunt as a cost-routing control, not a sandbox, a secrets scanner or an authorization boundary. Enabling a plugin also does not prove that your organization's managed hook settings permit it to run; include a real routing check in rollout acceptance.

## What bulk-reader and code-writer should do

Use bulk-reader for bounded extraction: identify exported interfaces, list configuration keys, summarize an established implementation pattern, or locate likely files for a subsequent targeted read. Ask for named symbols, relevant paths and uncertainty, rather than a free-form account of the repository.

Use code-writer for **new, predictable files with a trustworthy reference**, such as a test skeleton or configuration variant. The [code-write script](https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/scripts/code-write) requires a specification and reference file. With `--target`, it writes the generated result to disk instead of returning the entire file through standard output. Without a target, it prints the code, so the context-saving path is not automatic in every invocation.

Writing directly to disk is not acceptance. Generate into an isolated task branch or worktree, check the diff, run the relevant tests and inspect the sensitive sections. Existing files should not be treated as disposable destinations. If a generated test merely copies the implementation's wrong assumption, matching the neighboring tests does not make it useful.

Keep diagnosis, architecture, concurrency analysis and security-sensitive decisions on a workflow with sufficient reasoning and independent verification. Spotify reports that its example worker missed a subtle thread-safety issue. That is a limitation of the tested workflow, not proof that every inexpensive model is incapable of reasoning. Editing existing code still requires exact source, not guessed line numbers from a summary.

## Setup: three installation commands are not the whole prerequisite list

The [official plugin marketplace README](https://github.com/spotify/portal-ai-plugins) provides these Claude Code installation commands:

```
claude plugin marketplace add spotify/portal-ai-plugins
claude plugin install portal@portal
claude plugin install shunt@portal
```

In a **new Claude Code session**, run:

```
/portal:setup
```

You also need `jq`, Portal CLI authentication, a Portal instance with AiKA enabled, and accessible worker modes backed by a configured model. Check whether `bulk-reader` and `code-writer` exist in your instance. Do not assume that a mode described as public is available anonymously on every deployment.

A read-only mode discovery command is:

```
npx @spotify/portal-cli actions aika:list-modes --json --input '{"search":"bulk-reader"}'
```

Repeat with `code-writer`. Review the selected model and instructions before sending company code. The repository is Apache-2.0 licensed; that does not make Portal operation, worker inference or integration labor free. A Spotify music subscription is not the prerequisite described here.

## Current limits that launch summaries leave out

The reviewed [transport implementation](https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/scripts/lib/aika.sh) is more useful for troubleshooting than an old screenshot:

| Situation | Current source behavior | Sensible response |
| --- | --- | --- |
| Request too large | JSON input travels through command-line arguments; defaults cap payloads at 120,000 bytes on Linux and 400,000 elsewhere | Send fewer files or narrower questions; do not blindly raise the limit |
| Invocation takes too long | `SHUNT_TIMEOUT_SECONDS` defaults to 180 in the client | Check client and backend limits separately, then split work where practical |
| Mode selection is ambiguous | Names resolve by ownership/group/public precedence; IDs can select a specific mode | Verify the actual selected mode, model and instructions |
| A pinned mode is not applied | The wrapper rejects a response with no applied mode name | Repair mode configuration rather than accepting a generic answer |

Spotify's launch article reports typical 10–30-second round trips and mentions a 30-second invocation cap. The current wrapper's 180-second default is **not** a guarantee that every Portal backend accepts that duration. Record both the installed plugin version and your instance's behavior.

The transport is one-shot. A follow-up sends the chosen files again to the worker. Keeping them out of Claude's context does not eliminate the worker's input cost. For client repositories, review that additional processing path, retention terms, approved model providers and the handling of temporary request files before enabling delegation.

## How to decide whether shunt lowers your actual costs

Compare completed tasks, not isolated summaries. Anthropic's [Claude Code cost documentation](https://code.claude.com/docs/en/costs) distinguishes usage, model choice and context management; cached input and ordinary input should not be valued as if they were the same thing. Subscription capacity, metered API charges and a new worker bill are also not interchangeable.

Use this decision equation with your own measured values:

```
Net benefit per accepted task =
  avoided effective Claude cost
  - worker input and output cost
  - allocated incremental Portal cost
  - extra retries and verification effort
```

If a fixed subscription bill stays unchanged, the benefit may initially be more available capacity rather than cash saved. If caching already makes repeated reads inexpensive, a new network round trip can be a poor trade. If the summary omits a critical condition and Claude must reopen the whole file, the apparent saving can disappear.

Choose `SHUNT_MIN_LINES` from the team's file-size distribution and latency tolerance. Three hundred and fifty is a default, not a universal optimum. A long generated file containing repetitive declarations is a different workload from a shorter transaction handler where each line affects correctness.

## shunt versus native subagents and repository-context tools

Anthropic's [subagent documentation](https://code.claude.com/docs/en/sub-agents) already describes separate context windows, summaries returned to the parent and explicit model selection. Merely moving exploration out of the main conversation is not unique to shunt. The distinction is Spotify's Portal-mode integration plus its file-read routing hooks.

| Your immediate problem | First option to evaluate |
| --- | --- |
| You know the symbol or section already | A deterministic search or targeted read, without another model call |
| You need isolated exploration and do not use Portal | A native subagent with an explicitly chosen model and scoped tools |
| You already operate Portal and repeatedly ingest large files | A controlled shunt bulk-reader trial |
| You need a smaller, task-relevant repository map | A repository-context layer, not a generation worker |

Our [Ripwire repository-context review](/blog/ripwire-ai-repo-context-review-2026/) covers deterministic structural context. [Codag cost control](/blog/codag-cost-control/) covers compressed tool output. The [multi-model coding-agent buying guide](/blog/multi-model-ai-coding-agent-stack-2026/) addresses the wider team architecture. Use those pages for those decisions rather than treating shunt as a replacement for every context tool.

## A two-week acceptance plan for a shunt pilot

**Start with one repository and twenty representative tasks.** Include several large-file reads, some small targeted reads, one source-and-test comparison and a few repetitive new-file tasks. Keep difficult debugging in the sample as an exclusion check, not as work you expect the cheap worker to solve.

During the first week, baseline task completion time, effective model spend, cache behavior and review minutes without shunt. Repeat the same task categories with the plugin, holding prompts, model choices and acceptance criteria steady where possible. Record worker usage separately from Claude usage, and distinguish cold from warm cache runs.

During the second week, test the boundaries: a qualifying large read, an allowed targeted read, unavailable Portal, missing or ambiguous modes, an oversized batch and a worker response that is factually incomplete. Verify the resulting code and summaries against the original files. A blocked read followed by an endless retry loop is a failed pilot, not cost control.

Agree the release criteria before evaluating the results: no loss of accepted-task quality, a measured reduction in total task cost or a documented capacity benefit, tolerable tail latency and an owner for mode configuration. Publish the distribution of results, including regressions. Do not turn the best demonstration into a company-wide savings promise.

## When to implement it, and when to leave your workflow alone

A strong candidate already uses Portal, has measurable large-file context waste, and can assign an owner to worker prompts, data access and evaluations. A weak candidate mostly performs small exact edits, lacks approved worker-model access, or cannot explain how a shorter answer will be checked.

Wavect's [AI consulting and implementation service](/services/artificial-intelligence/) can scope a measured coding-agent cost review before you add another platform. The [Twinsoft AI case study](/case-studies/twinsoft-ai/) provides adjacent AI-delivery context, not evidence that Wavect deployed shunt there. The [custom software versus off-the-shelf guide](/software-development-guide/custom-software-vs-off-the-shelf/) helps separate a small integration from a platform commitment.

[Scope a coding-agent token-routing pilot](/contact/) with your current usage breakdown, one representative repository and the checks an accepted change must pass. The deliverable should be a defensible routing decision, not a promised percentage.

**Verdict:** copy the boundary, not the headline. Delegate well-defined reading and repetitive generation only where verified savings exceed worker cost, latency and rework. Keep exact edits and consequential judgment on the path that can prove them correct.

## Frequently asked questions

### Does Spotify shunt reduce the whole Claude Code bill by 90%?

The reported figure concerns estimated Claude read-context tokens in selected bulk-read scenarios. Worker usage, Portal costs, caching, retries and verification determine the actual end-to-end saving.

### Can I use Spotify shunt without Portal?

The official plugin invokes AiKA modes through Portal CLI and requires an authenticated Portal instance with AiKA enabled. A native subagent can implement a different delegation workflow, but that is not the same installation.

### Does shunt force all code generation onto a cheaper model?

No. The README explicitly says code-writer has no hook enforcement. Its use is skill-guided. Supported bulk-read routing is the enforced part.

### Should I always use the 350-line threshold?

No. It is a configurable default, not a universal optimum. Choose it from your file-size distribution, worker latency, cache behavior and accepted-task results.

### Is Spotify shunt a security boundary?

No. Cost-routing hooks are not a sandbox or an authorization system. Review code-processing destinations, credentials, plugin permissions and generated files separately.

Agent engineering

## Continue through this cluster

Coding agents, MCP, context systems, evaluation and the controls required for dependable automation.

[Start with the cornerstone**Graph Engineering for AI Agents: When Does a Knowledge Graph Pay Off?**](/blog/graph-engineering-ai-agents/)

- [OpenBot Review: Self-Hosted AI Coworkers, Costs & Controls](/blog/openbot-self-hosted-ai-coworkers-review/)
- [Ramp Inspect Architecture 2026: Background Coding Agents at Scale](/blog/ramp-inspect-background-coding-agent-infrastructure-2026/)
- [Model Hardware Standard: Enterprise Guide to Physical AI](/blog/model-hardware-standard-enterprise-guide/)
- [Fonio AI Review 2026: Pricing, API, GDPR & Build vs Buy](/blog/fonio-ai-review-build-vs-buy-2026/)
- [Mosaic (YC S26) Review: Shared Memory for Team AI Agents](/blog/mosaic-yc-s26-shared-agent-sessions-review/)

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

10 min read · 12 Sep 2026 Last reviewed September 12, 2026

[**Next**](/blog/smarter-token-usage-with-your-ai-coding-agent/)

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/#organization",
      "@type": [
        "Organization",
        "ProfessionalService",
        "LocalBusiness"
      ],
      "employee": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "founder": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "legalRepresentative": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "name": "Wavect GmbH",
      "subjectOf": {
        "@id": "https://wavect.io/verified-claims.json#dataset",
        "@type": "Dataset",
        "creator": {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        "description": "A machine-readable registry of quantitative and qualitative claims published by Wavect, with review dates, localized page appearances and public third-party citations where available.",
        "inLanguage": "en",
        "isAccessibleForFree": true,
        "license": "https://creativecommons.org/licenses/by/4.0/",
        "name": "Wavect verified publication claims",
        "url": "https://wavect.io/verified-claims.json"
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/team/kevin-riedl/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Kevin Riedl",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796365",
        "https://www.linkedin.com/in/wsdt",
        "https://github.com/wsdt"
      ],
      "url": "https://wavect.io/team/kevin-riedl/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/team/christof-jori/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Christof Jori",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796367",
        "https://www.linkedin.com/in/jocr77/",
        "https://github.com/jo-chris"
      ],
      "url": "https://wavect.io/team/christof-jori/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/#website",
      "@type": "WebSite",
      "inLanguage": [
        "en",
        "de",
        "es",
        "zh"
      ],
      "name": "Wavect",
      "potentialAction": {
        "@type": "SearchAction",
        "query-input": "required name=search_term_string",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://wavect.io/search/?q={search_term_string}"
        }
      },
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/blog/spotify-shunt-claude-code-token-routing/#webpage",
      "@type": "WebPage",
      "dateModified": "2026-09-12",
      "inLanguage": "en",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-09-12",
      "url": "https://wavect.io/blog/spotify-shunt-claude-code-token-routing/"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "abstract": "Spotify shunt routes large file reads and predictable code generation through Portal AiKA worker modes. Its reported 90% saving concerns estimated Claude read-context tokens in selected bulk-read scenarios, not the combined bill. You need an authenticated Portal instance with AiKA, accessible modes and a configured model. Read hooks enforce supported routing; code-writer remains skill-guided. Compare worker costs, caching, latency and verification before adopting it.",
  "articleBody": " Blog overview/AI and agents/Agent engineering Spotify shunt Review: Claude Code Token Savings, Setup and Limits TL;DR Spotify shunt routes large file reads and predictable code generation through Portal AiKA worker modes. Its reported 90% saving concerns estimated Claude read-context tokens in selected bulk-read scenarios, not the combined bill. You need an authenticated Portal instance with AiKA, accessible modes and a configured model. Read hooks enforce supported routing; code-writer remains skill-guided. Compare worker costs, caching, latency and verification before adopting it. Spotify shunt is worth testing when Claude Code repeatedly opens large files to answer narrow questions. It is not evidence that your entire AI coding bill will fall by 90%. The useful decision is whether a cheaper reader can return enough accurate context to complete the task without creating extra verification work. Spotify's engineering article describes two Portal AiKA modes: bulk-reader for focused answers over files and code-writer for predictable generation from an existing example. Its examples use Gemini 2.5 Flash at temperature 0.2. Those are configurable worker choices, not a requirement to replace Claude as the main coding agent. This is a source-based review, checked on 12 September 2026, not a Wavect production benchmark. It concerns shunt in spotify/portal-ai-plugins, not another project with the same name. The broader coding-agent token-cost playbook covers caching, batching and general cost control. Here, the question is narrower: when does Spotify's file-I/O delegation actually pay off? Independence and trademarks: Wavect publishes this page and is itself a provider, so we have a commercial interest in it. We are not affiliated with, endorsed by or partnered with the other companies named here, and all third-party company names, brands and trademarks are the property of their respective owners. Statements about other providers are taken from publicly available sources, primarily their own published pages, as of the review date shown on this page, and may have changed since. Please verify them directly before you decide. This page was written to the best of our knowledge and with the intent to remain objective. If you believe anything here is inaccurate or unfair, write to us and we will correct it: office@wavect.io What did the reported 90% saving measure? Start with the denominator. The public benchmark specification describes Claude-context token savings and estimates code tokens as characters divided by four. This is an approximation, not a provider billing ledger. Its included TypeScript fixtures are also not the Java monorepo described in the published results, so running the fixture harness is not an exact reproduction of that experiment. The shunt README reports these results from a 162,000-line Java monorepo: Published scenario Lines read Without shunt With shunt Publisher-reported saving One large file 4,014 33,684 tokens 5,737 tokens 82% Source file and tests 7,408 75,990 tokens 4,148 tokens 94% Files across services 1,281 16,221 tokens 821 tokens 94% The README reports a 90% mean. Its separate code-writing row describes 833 lines written to disk, but gives no comparable percentage. Neither the table nor that mean establishes a 90% reduction in combined Claude, worker, platform and engineering costs. The rows above retain the publisher's percentages rather than presenting them as independently remeasured figures. For example, consider an explicitly hypothetical read: Claude previously received 40,000 tokens; a worker now consumes those 40,000, produces a 4,000-token summary, and Claude receives that summary. Claude's read context shrinks 90%, while total tokens across the two models are 48,000 before other overhead. Different token prices can still make this cheaper. Token reduction and bill reduction are different measurements. Why a hook changes what CLAUDE.md cannot guarantee A repository instruction asks an agent to behave a certain way. A tool hook can intervene before a matching tool call runs. Anthropic's hook reference documents that distinction through PreToolUse decision control. Spotify's Read-hook implementation checks the requested file's line count. Its default threshold is 350 lines, adjustable through SHUNT_MIN_LINES; an unrestricted read of a larger file is redirected toward bulk-reader. Reads with an explicit offset or limit pass through, allowing Claude to inspect the exact section needed for an edit. At the default threshold, a 350-line file is not above the limit. The three layers have different jobs: Layer Responsibility What it does not establish Hooks Intercept supported broad reads and request delegation Universal enforcement across every possible tool or data path Wrapper scripts Send the task and files through Portal and handle the response Whether the answer is complete or correct Skills Explain when and how to invoke the workers A mandatory decision for every generation",
  "articleSection": "Engineering",
  "author": {
    "@id": "https://wavect.io/team/kevin-riedl/#person",
    "@type": "Person",
    "name": "Kevin Riedl",
    "sameAs": [
      "https://www.wikidata.org/wiki/Q139796365",
      "https://www.linkedin.com/in/wsdt",
      "https://github.com/wsdt"
    ],
    "url": "https://wavect.io/team/kevin-riedl/"
  },
  "citation": [
    {
      "@type": "WebPage",
      "name": "Spotify's engineering article",
      "url": "https://engineering.atspotify.com/2026/9/portal-by-spotify-cut-my-claude-code-token-usage-by-90"
    },
    {
      "@type": "WebPage",
      "name": "benchmark specification",
      "url": "https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/evals/benchmarks.json"
    },
    {
      "@type": "WebPage",
      "name": "shunt README",
      "url": "https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/README.md"
    },
    {
      "@type": "WebPage",
      "name": "hook reference",
      "url": "https://code.claude.com/docs/en/hooks"
    },
    {
      "@type": "WebPage",
      "name": "Read-hook implementation",
      "url": "https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/hooks/check-file-size"
    },
    {
      "@type": "WebPage",
      "name": "code-write script",
      "url": "https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/scripts/code-write"
    },
    {
      "@type": "WebPage",
      "name": "official plugin marketplace README",
      "url": "https://github.com/spotify/portal-ai-plugins"
    },
    {
      "@type": "WebPage",
      "name": "transport implementation",
      "url": "https://github.com/spotify/portal-ai-plugins/blob/main/plugins/shunt/scripts/lib/aika.sh"
    },
    {
      "@type": "WebPage",
      "name": "Claude Code cost documentation",
      "url": "https://code.claude.com/docs/en/costs"
    },
    {
      "@type": "WebPage",
      "name": "subagent documentation",
      "url": "https://code.claude.com/docs/en/sub-agents"
    }
  ],
  "dateModified": "2026-09-12",
  "datePublished": "2026-09-12",
  "description": "Spotify shunt routes large file reads and predictable code generation through Portal AiKA worker modes. Its reported 90% saving concerns estimated Claude read-context tokens in selected bulk-read scenarios, not the combined bill. You need an authenticated Portal instance with AiKA, accessible modes and a configured model. Read hooks enforce supported routing; code-writer remains skill-guided. Compare worker costs, caching, latency and verification before adopting it.",
  "headline": "Spotify shunt Review: Setup, Savings and Limits",
  "image": "https://wavect.io/img/blog/headers/header_spotify-shunt-claude-code-token-routing.png",
  "inLanguage": "en",
  "keywords": "Claude Code, Token routing",
  "mainEntityOfPage": {
    "@id": "https://wavect.io/blog/spotify-shunt-claude-code-token-routing/",
    "@type": "WebPage"
  },
  "publisher": {
    "@id": "https://wavect.io/#organization",
    "@type": [
      "Organization",
      "ProfessionalService",
      "LocalBusiness"
    ]
  },
  "url": "https://wavect.io/blog/spotify-shunt-claude-code-token-routing/",
  "wordCount": 2520
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "item": "https://wavect.io/",
      "name": "Home",
      "position": 1
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/overview/",
      "name": "Blog overview",
      "position": 2
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/topics/ai-agents/",
      "name": "AI and agents",
      "position": 3
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/clusters/agent-engineering/",
      "name": "Agent engineering",
      "position": 4
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/spotify-shunt-claude-code-token-routing/",
      "name": "Spotify shunt Review: Setup, Savings and Limits",
      "position": 5
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The reported figure concerns estimated Claude read-context tokens in selected bulk-read scenarios. Worker usage, Portal costs, caching, retries and verification determine the actual end-to-end saving."
      },
      "name": "Does Spotify shunt reduce the whole Claude Code bill by 90%?"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The official plugin invokes AiKA modes through Portal CLI and requires an authenticated Portal instance with AiKA enabled. A native subagent can implement a different delegation workflow, but that is not the same installation."
      },
      "name": "Can I use Spotify shunt without Portal?"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. The README explicitly says code-writer has no hook enforcement. Its use is skill-guided. Supported bulk-read routing is the enforced part."
      },
      "name": "Does shunt force all code generation onto a cheaper model?"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. It is a configurable default, not a universal optimum. Choose it from your file-size distribution, worker latency, cache behavior and accepted-task results."
      },
      "name": "Should I always use the 350-line threshold?"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. Cost-routing hooks are not a sandbox or an authorization system. Review code-processing destinations, credentials, plugin permissions and generated files separately."
      },
      "name": "Is Spotify shunt a security boundary?"
    }
  ]
}
```
