◉CLAUDE LABJP
●2.1.296 — Subagents can set their own autoCompactWindow, and an env var pins the model used by workflow agents●AGENTS — Managed Agents gain dynamic workflows in beta: an agent can build a run for work with many pieces (Oct 9)●SONNET 4.5 — Retires on the Claude API on 11/30, 48 days left. Migrate to Sonnet 5.5●Q&A — A write-up shows how to stop a streaming call midway so a closed tab stops being billed●WORKTREE — Running claude --worktree on one repo in parallel: what to settle first, as one write-up lays it out●NEW — Stop making it reread the whole notes file: look up one section by number●2.1.296 — Subagents can set their own autoCompactWindow, and an env var pins the model used by workflow agents●AGENTS — Managed Agents gain dynamic workflows in beta: an agent can build a run for work with many pieces (Oct 9)●SONNET 4.5 — Retires on the Claude API on 11/30, 48 days left. Migrate to Sonnet 5.5●Q&A — A write-up shows how to stop a streaming call midway so a closed tab stops being billed●WORKTREE — Running claude --worktree on one repo in parallel: what to settle first, as one write-up lays it out●NEW — Stop making it reread the whole notes file: look up one section by number
Articles/API & SDK
⬡ API & SDK/2026-10-13Intermediate

Haiku 5.5 is cheaper per token, but your bill jumps fivefold past about 77k Haiku 4.5 tokens

On the price sheet, Haiku 5.5 costs roughly a tenth of Haiku 4.5. But the same text becomes about 30% more tokens, and a prompt over 100k tokens is billed at five times the rate. Here is the boundary in Haiku 4.5 terms, a script I actually ran, and the changes that return a 400.

Claude API127Haiku 5.5Migration7Pricing6Tokens

When I first read the Haiku 5.5 price sheet, input at $0.10 per million tokens, I assumed I had dropped a digit. Haiku 4.5 was $1.00, so I looked twice.

I had not misread it. But the same table has another row: any request whose input goes over 100,000 tokens is billed at five times that rate. Starting a migration with "it got cheaper" in my head felt like setting myself up for the opposite surprise, so I ran the numbers by hand first.

What I'd like to say up front is that the boundary is not 100k if you are counting in Haiku 4.5 tokens. It is about 77k, because the tokenizer changed.

The official numbers (checked on October 13, 2026)

ItemHaiku 4.5Haiku 5.5
Model IDclaude-haiku-4-5claude-haiku-5-5 (no dated ID)
Input / output per MTok$1 / $5$0.10 / $0.50 (input up to 100k)
Requests over 100kSame rate$0.50 / $2.50 (5x)
Cache read$0.10$0.01 ($0.05 over 100k)
Context / max output200k / 64k1M / 128k
Tokens for the same textbaselineabout 30% more

Two details are easy to miss. The 100k check counts cache reads and writes too, and it is applied per request, so a cache hit does not save you if the total goes over.

Computing the boundary

I turned the official numbers into a function that takes the token count you were seeing on Haiku 4.5 and returns the cost on 5.5. The output below is from actually running this script. Nothing was sent to the API; it is arithmetic only.

"""Haiku 4.5 -> 5.5: 同じ呼び出しの1リクエスト単価を比べる(USD / 100万トークン)"""
INFLATE = 1.30            # 公式: 同じ文章が約30%多いトークンになる
P45 = dict(inp=1.00, out=5.00, cache=0.10)
P55_LO = dict(inp=0.10, out=0.50, cache=0.01)   # 入力全体が 100,000 以下
P55_HI = dict(inp=0.50, out=2.50, cache=0.05)   # 100,000 超(5倍)
THRESH = 100_000
 
def cost45(fresh, cached, out):
    p = P45
    return (fresh*p["inp"] + cached*p["cache"] + out*p["out"]) / 1e6
 
def cost55(fresh, cached, out):
    fresh, cached, out = fresh*INFLATE, cached*INFLATE, out*INFLATE
    # 判定は cache 読み書きを含む入力の合計
    p = P55_HI if (fresh + cached) > THRESH else P55_LO
    return (fresh*p["inp"] + cached*p["cache"] + out*p["out"]) / 1e6, p is P55_HI
 
if __name__ == "__main__":
    print(f"{'4.5換算の入力':>12} {'4.5':>9} {'5.5':>9} {'比':>6}  段")
    for n in (10_000, 50_000, 70_000, 76_000, 77_000, 80_000, 120_000):
        a = cost45(n, 0, 1000)
        b, hi = cost55(n, 0, 1000)
        print(f"{n:>12,} {a:9.5f} {b:9.5f} {b/a:6.2f}  {'上段' if hi else '下段'}")
    print("境目(4.5換算):", f"{THRESH/INFLATE:,.0f}")
    # 境目をまたぐ前後で 5.5 自身の単価がどれだけ跳ねるか
    lo = cost55(76_900, 0, 1000)[0]; hi = cost55(77_000, 0, 1000)[0]
    print(f"76,900 -> 77,000 : {lo:.5f} -> {hi:.5f} ({hi/lo:.2f}倍)")
    # 同じ 90,000(4.5換算) をキャッシュ読み 60,000 + 新規 30,000 で送る場合
    print("cache込み 90,000:", f"4.5={cost45(30_000,60_000,1000):.5f}", f"5.5={cost55(30_000,60_000,1000)[0]:.5f}")

Output:

    4.5換算の入力       4.5       5.5      比  段
      10,000   0.01500   0.00195   0.13  下段
      50,000   0.05500   0.00715   0.13  下段
      70,000   0.07500   0.00975   0.13  下段
      76,000   0.08100   0.01053   0.13  下段
      77,000   0.08200   0.05330   0.65  上段
      80,000   0.08500   0.05525   0.65  上段
     120,000   0.12500   0.08125   0.65  上段
境目(4.5換算): 76,923
76,900 -> 77,000 : 0.01065 -> 0.05330 (5.01倍)
cache込み 90,000: 4.5=0.04100 5.5=0.02665

(The column labels are in Japanese: input in 4.5 terms, 4.5 cost, 5.5 cost, ratio, and lower/upper tier.)

Two things differed from what I expected.

  • Even past the boundary, 5.5 stays cheaper than 4.5 (the ratio moves from 0.13 to 0.65). Migrating does not cost you money.
  • Compared with itself, though, 5.5 jumps 5.01x between 76,900 and 77,000. Trimming a few hundred tokens from a prompt can cut that request's cost to a fifth.

"It's cheaper, so I can stop worrying" and "it's worth staying under the line" were both true.

What returns a 400

A request that doesn't run doesn't bill, so here is the other half. According to the official migration guide, code that worked on 4.5 changes like this:

On 4.5On 5.5
thinking: {"type": "enabled", "budget_tokens": N}400. Use adaptive with output_config.effort
temperature / top_p / top_kRemove them. Any top_k is a 400; top_p must be 0.99
Trailing assistant message (prefill)400, even with thinking off. End on a user turn
computer_20250124400. Use computer_toolset_20260801
Sending thinking blocks back after editing system, tools, or earlier turns400

The scanner I wrote for Sonnet 5.5 works almost as is; add patterns for the top_p rule and the computer-use tool.

One more catch: thinking tokens count toward max_tokens. A limit that was comfortable on 4.5 can stop right after a thinking block with stop_reason: "max_tokens" and an empty answer.

resp = client.messages.create(
    model="claude-haiku-5-5",
    max_tokens=4000,                      # leave headroom even if 4.5 used 1000
    thinking={"type": "adaptive"},
    output_config={"effort": "low"},      # start light tasks at low
    messages=[{"role": "user", "content": text}],
)
# Reading that survives a leading thinking block
answer = next((b.text for b in resp.content if b.type == "text"), "")
if resp.stop_reason == "max_tokens" and not answer:
    raise RuntimeError("Hit the limit inside thinking; raise max_tokens")

As an indie developer calling the API from small scripts, I'll apply this to my own calls first, since any place that reads the first content block as the answer is the most likely to break.

The order I'd work in

  1. Pull the input-token distribution from your 4.5 logs and count how many calls exceed 77k.
  2. For those, see whether the prompt can shrink (stale history, duplicated documents) before anything else. That removes the fivefold step.
  3. Fix the 400 items and give max_tokens headroom.
  4. Once it runs, lower effort to find the quality and cost balance.

Priority Tier is not supported on Haiku 5.5, so if your setup relied on it, capacity needs a separate estimate.

One thing to try today

Take the top 1% of your input sizes from the logs and check whether any exceed 77k. If none do, you can skip most of this article.

The low price list only applies cleanly while you stay on the near side of the line. That's the check I'd like to make first on every new model.

Sources: Claude Haiku 5.5 migration guide, What's new in Claude Haiku 5.5, Pricing

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ API & SDK2026-10-08
Before Sonnet 4.5 retires, one script to find the arguments that will return a 400
claude-sonnet-4-5 retires on November 30. Swapping the model ID is not enough: budget_tokens, prefill, and tool_choice will fail. Here is a scanner built from the official migration guide, its real output, and the order I would fix things in.
⬡ API & SDK2026-08-14
Move the Prompt Tools API Into Your Own Scripts Before Workbench Closes on August 17
The legacy Workbench and three experimental prompt endpoints shut down on August 17, 2026. Here is how to count what actually depends on them, plus working local replacements for templatize_prompt and improve_prompt with real output.
⬡ API & SDK2026-10-07
Before You Switch Models, Replay Your Own Call Shapes Against the Candidate for a Few Tokens
Change a model ID and the first production request is where a 400 shows up. Here is a small replay script that checks your own call shapes against a candidate model with max_tokens 16 before you switch.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links