← All reviews
Analysis · September 6, 2026 · 9 min read

Spotify's 90% token cut, reproduced — and why 350 lines is the number that actually matters

Delegating a file read to a cheaper model saves tokens the moment the file is bigger than the summary — which happens sooner than you'd guess, at about 90 lines. Doing it at 90 lines is still a mistake. Every delegation costs roughly twenty seconds, and at that size you are buying 165 tokens with it. Here is the measured curve, and why Spotify's conservative-looking default is the right one.

The 30-second version

A Spotify engineer published a post on September 4 with a headline number that did what headline numbers do: Portal cut my Claude Code token usage by 90%. It reached the front page of Hacker News with 267 points.

The mechanism is simple enough to copy in an afternoon, and it does not need Spotify’s platform: Claude Code hooks intercept a file read, and if the file is big, a cheaper model reads it instead and hands back a summary. Your context gets the summary. That is the whole trick.

We reproduced it on an unrelated codebase and the savings are real — 85.7% on large files, close enough to 90% to call it corroborated.

But the interesting number in that post is not 90%. It is 350 — the default line threshold below which the tool does not bother delegating. Our measurements say the token break-even is around 90 lines, four times lower. The gap between those two numbers is the whole lesson, and it is made entirely of seconds.

What Portal actually does

Portal is Spotify-internal and not open source, so nobody outside is going to run it. The component that matters is called Shunt, and its description is the reusable part:

“Claude Code hooks fire before every tool call. Shunt registers two PreToolUse hooks.”

When Claude tries to read a file, the hook checks its length. Per the post: “If the file exceeds a configurable line threshold (default: 350), the hook blocks the read…” — and the read is redirected to a cheaper worker model, Gemini 2.5 Flash in the examples, which returns a summary.

Everything load-bearing here is generic. PreToolUse hooks are a documented Claude Code feature, “a cheap model” is any model you can call from a shell, and the summary comes back as ordinary tool output. If you have ever thought about wiring a subagent to pre-digest files, this is that idea with a hook doing the routing instead of you.

What the 90% measures

Worth being precise, because the number travels further than its caveats:

“Tested against a Java monorepo across four scenarios, measuring tokens Claude would consume reading files directly vs. consuming the bulk-reader’s summary or writing code via the code-writer. Mean bulk-read savings were around a whopping 90%.”

So: one Java monorepo, four scenarios, and the comparison is direct read versus summary. It is a mean over bulk reads, not a 90% cut to anyone’s bill. What it tells you is that summarising a large file is roughly ten times cheaper than reading it. What it does not tell you is what share of your own token spend is large-file reading — which is the number that decides whether any of this is worth wiring up.

The post publishes no per-scenario breakdown, so 90% is the only figure available from the source.

We reproduced it on a different codebase

Different language, different worker model, same shape. Twelve real source files from two unrelated projects (JavaScript and Python, 43 to 678 lines), summarised by Claude Haiku 4.5 with a bulk-reader prompt, measured with Claude Code’s own reported token usage rather than an estimate.

Method: run each file through the worker with claude -p --output-format json, and subtract a control run with no file attached. The control came back at exactly 23,624 input tokens on two separate runs, so the delta is the file.

FileLinesRead directlySummarySaved
config.js43578644−66
check-articles.py49324610−286
http.js87917752+165
gen-llms.py1021,212799+413
identity.js1141,549983+566
validate.js1311,619858+761
verify.js1712,422938+1,484
health.js1772,625806+1,819
fetch.js2943,7101,096+2,614
views.js4709,9771,319+8,658
index.js6038,5541,384+7,170
store.js6789,0661,236+7,830

Apply Spotify’s actual policy — delegate only files of 350 lines or more — and the three qualifying files go from 27,597 tokens to 3,939. That is an 85.7% reduction, on a codebase with no relationship to theirs. The headline replicates.

The break-even nobody published

Look at the summary column rather than the savings column. Across files spanning 324 to 9,977 tokens — a thirty-fold range — the summaries only span 610 to 1,384 tokens. Summary length is close to flat.

That is the structural fact everything else follows from. A summary has a floor: describing what a file does, its exports, and anything surprising takes several hundred tokens whether the file is 40 lines or 700. So delegation does not scale savings up from zero; it replaces the file with a roughly fixed cost, and you win only when the file exceeds that cost.

Which puts the crossover between 49 and 87 lines in this data. Below it you actively lose: our two smallest files cost 902 tokens to read directly and 1,254 tokens to delegate — 39% worse than just reading them.

That floor is prompt-dependent, and this is the one number you can move. Our bulk-reader prompt said “be concise” without a hard cap. Give the worker a strict token budget and the floor drops, dragging the break-even down with it. Anyone implementing this should tune the summary prompt before touching the threshold.

Why the token break-even is the wrong threshold

Here is where the 90% headline actively misleads, and where the 350 comes from.

Delegation is not free in wall-clock time. Spotify measured it: “Each delegation is a network round-trip: Claude Code to the Portal backend to the worker model and back. Responses typically take 10–30 seconds, and Portal caps a single invocation at 30 seconds.”

We measured the same thing on the leanest possible path — Claude Code calling Haiku directly, no Portal backend, no extra service hop — and got 19.0 and 20.1 seconds for the 678-line file. The latency is not Portal’s architecture. It is inherent to having another model read a file and write about it.

Now price the savings in seconds, using twenty as the round-trip cost:

File sizeTokens savedSeconds per 1,000 tokens saved
87 lines165121.2
114 lines56635.3
171 lines1,48413.5
294 lines2,6147.7
470 lines8,6582.3
678 lines7,8302.6

Delegating at the token break-even costs about 121 seconds per 1,000 tokens saved. Delegating at Spotify’s threshold costs about 2.5. That is a 47× swing in value, and it is why 350 lines is not a cautious guess — it is roughly where the trade stops being embarrassing.

The counterintuitive consequence: being more aggressive lowers your average savings. Delegating all twelve files scores 73.2%; delegating only the large ones scores 85.7%. The small files dilute the win and cost you a minute of waiting for the privilege.

What you still can’t delegate

The post is honest about the ceiling, and both limits are worth quoting because they bound the whole technique.

On editing: “The worker model’s summaries don’t include reliable line numbers. If Claude needs to make edits based on the analysis, it still has to read the specific section directly.” So a delegated read that leads to an edit gets paid for twice.

On reasoning: “The worker model found surface-level patterns but missed a subtle thread-safety bug in my testing. Claude spotted it in seconds once given the right context.”

That second one deserves more weight than it usually gets. A summary is a lossy compression chosen by a weaker model, and what it drops is exactly the subtle thing you were hoping to find. Delegation is a read-path optimisation — it reduces what enters context, not what has to be understood. Use it to decide whether a file is relevant, not to conclude that it is fine.

What to do

  • Check whether large-file reading is actually your cost centre. Run /usage and look at where tokens go. If your sessions are long conversations over a handful of files, this technique has nothing to offer you; the startup overhead and cache churn are a bigger lever.
  • If you build it, start the threshold high. 350 lines is a well-priced default. The instinct to lower it “because it still saves tokens at 90 lines” is the mistake this data is here to prevent.
  • Tune the summary prompt before the threshold. The summary floor — 610 tokens at its smallest here — is the term you control. A hard token cap on the worker’s output moves the break-even down far more cheaply than adding round trips.
  • Budget the latency honestly. ~20 seconds per delegated read is the blocking tax every PreToolUse hook charges, and it lands on the critical path of an agent you are waiting on.
  • Never delegate the read you are about to edit. You will read it again anyway, at full price.

The real lesson

The 90% is real, replicates on a foreign codebase, and is the least useful number in the post. It measures a ratio between two ways of ingesting one large file, in a scenario chosen because delegation works there.

The number that governs whether this helps you is the threshold — and the threshold is not a token calculation at all. It is the point where the tokens saved are worth twenty seconds of your agent standing still. That is a different question, with a different answer, four times further up the file-size curve than the token math alone suggests.

Optimisations that report their wins as percentages of the thing they optimise will always look like this. The honest version of the headline is narrower and more useful: on files over ~350 lines, having a cheap model read it first costs you twenty seconds and saves you most of the context.

Companion reading

Sources

  1. Spotify Engineering — Portal by Spotify cut my Claude Code token usage by 90%, by Dimitri Mazmanov (September 4, 2026). Primary source for the mechanism, the 90% figure, the 350-line default, and the latency and limitation quotes.
  2. Hacker News — discussion thread (267 points, 171 comments).
  3. Anthropic — Claude Code hooks documentation. PreToolUse, the hook type Shunt registers.
  4. Anthropic — Claude Code costs and usage. The /usage breakdown used to check where tokens actually go.
  5. Anthropic — Claude Code subagents. The native alternative to a custom delegation hook.
  6. Anthropic — model overview. Claude Haiku 4.5, the worker model in our reproduction.

Our own measurements are described in full above: twelve files, Claude Haiku 4.5 as the worker, token counts from claude -p --output-format json, control baseline 23,624 tokens verified on two runs.

FAQ

What is Portal by Spotify and how did it cut token usage by 90%? Portal is Spotify-internal platform tooling; the relevant component, Shunt, registers two PreToolUse hooks in Claude Code. When Claude tries to read a file longer than a configurable threshold (default 350 lines), the hook blocks the read and redirects it to a cheaper worker model — Gemini 2.5 Flash in the examples — which returns a summary instead. Portal is not open source, but the mechanism is generic: hooks plus a cheap model.

Does the 90% hold up on other codebases? Broadly yes. We reproduced the pattern on an unrelated JavaScript and Python codebase with Claude Haiku 4.5 as the worker. Applying Spotify’s actual default policy — delegate only files of 350 lines or more — replaced 27,597 file tokens with 3,939 summary tokens, an 85.7% reduction. Close enough to ~90% to count as independent corroboration.

At what file size does delegation start saving tokens? Between 49 and 87 lines in our data. A 43-line file cost 578 tokens read directly but produced a 644-token summary — a net loss. The 87-line file was the first to come out ahead, by 165 tokens. Summaries barely grow with file size: across files spanning 324 to 9,977 tokens, summaries ranged only from 610 to 1,384.

Why is the default 350 lines and not the token break-even? Because latency is the other cost. Spotify measured 10–30 seconds per delegation; we measured 19–20 seconds locally with no Portal backend in the path. At 87 lines you spend ~20 seconds to save 165 tokens — about 121 seconds per 1,000 tokens saved. At 470–678 lines the same 20 seconds buys 7,000–8,600 tokens, around 2.5 seconds per 1,000. A ~47× difference in value.

What can’t you delegate? Editing and reasoning, per the author. Summaries lack reliable line numbers, so an edit still requires reading the section directly. And the worker model “found surface-level patterns but missed a subtle thread-safety bug” that Claude caught once given context. Use delegation to decide whether a file is relevant, not to conclude that it is fine.

Should I lower the threshold to save more? No. Delegating all twelve of our files scored 73.2% versus 85.7% for large files only — small files drag the average down, and two lost tokens outright. Tune the summary prompt with a hard token cap instead; that lowers the summary floor and moves the break-even down without adding slow round trips.

Was this helpful?

Related reading


Reviews independently produced · Editorial policy

Read more reviews →