avatar vian's notes

Learning in public, one post at a time

  • HOME
  • CATEGORIES
  • TAGS
  • ARCHIVES
  • ABOUT
Home What I Changed in 9router
Post

What I Changed in 9router

Posted Jun 17, 2026 Updated Jul 9, 2026
By Alvian
3 min read

The npm install output scrolled up the terminal. I watched, braced for the usual 30-second wait. It finished in four seconds. The node_modules folder was 2.5MB instead of 200MB.

Then the server started. 200 milliseconds instead of fifteen seconds.

I sat there for a moment, surprised at how light it felt. I’d been bracing for a heavy dev loop and got something that felt almost empty.

This was the first thing I changed after forking 9router: the monorepo split.

The upstream was a Next.js monolith — dashboard, routing engine, CLI, all in one blob. Every change meant waiting for Next.js to recompile. The CLI npm install pulled in the entire dashboard dependency tree. I ripped it apart: the API server (Hono) got its own workspace, the dashboard (Next.js) another, the CLI got esbuild bundling and its own package. Now I can update the routing engine without touching the dashboard — or never install the dashboard at all.

But the split was just the starting point. Daily use taught me what a router actually needs.

Tiered fallback wasn’t a nice-to-have. I discovered this at 1am during a production incident — primary provider hit its rate limit. The fallback chain took the next request without a pause. 9router chains providers in tiers: subscription accounts first, then cheap APIs (MiniMax at $0.20/M tokens), then free ones (Kiro, OpenCode Free, Vertex credits). When a paid provider says no, the next tier picks up. No retry spinner. No waiting.

Multiple accounts per provider. One account is a single point of failure. Upstream 9router already supported round-robin with sticky sessions — requests stick to one account until a configurable limit, then rotate. If an account gets model-level rate-limited, it’s skipped automatically. I didn’t appreciate this until I hit that lock and watched the router route around it.

Token compression felt like finding money. The RTK saver compresses tool_result content server-side — 20-40% fewer tokens per request, applied transparently. The agent never knows it’s happening. The bill just shrinks.

I rebuilt the headroom API after the split. The compression proxy was an upstream feature, but its API was still wired into the old monolithic server. I reimplemented the status, start, and stop endpoints on the new Hono server — auth-gated with localhost detection plus a CLI token for remote control.

OAuth tokens expire mid-session. 9router handles proactive refresh — before every request, it checks credentials near expiry and refreshes them. This killed a recurring failure mode that had been silently wasting my time.

The real payoff was the combo system. Routing config lives in ~/.ai/combos.json. Named model tiers with specific fallback strategies:

1
2
3
Cheap:   round-robin over oc/big-pickle, oc/deepseek-v4-flash-free, gemini flash lite
Premium: chain through ocg/deepseek-v4-pro, qwen3.7-max, qwen3.6-plus
Deep-Thinker: chain Architect into Premium

Add a model alias to a combo and it joins the rotation. No code changes. The import/export format evolved alongside the strategies — version 2 emits the full config object instead of the legacy roundRobin boolean. Export JSON, paste into any AI chat for analysis, get back a tuned config, import. No dashboard required.

The entire operational state lives in ~/.9router/: a SQLite database with provider connections, OAuth tokens, and usage stats; a headroom proxy directory; a vendored cloudflared binary; a few config files. No external databases. No cloud services. Everything is local files and SQLite.

I didn’t plan any of this. Each change came from a specific failure — rate limit at midnight, slow startup every edit, token expiry mid-request, locked account on a Friday deploy. The router became what the failures demanded.

See how I found 9router in the first place and why it needed a tunnel to be useful. Warp Came Back Around is where all this finally clicked.


Sources: 9router upstream README (RTK 20-40% token savings, tier 2 cheap providers including MiniMax) · MiniMax API pricing (M2.7, M2.5, M2.1 at $0.30/M input)

9router monorepo headroom rt tooling
This post is licensed under CC BY-NC 4.0 by the author.
Share

Recently Updated

  • Headroom, Round Two: Four Walls Between Me and a Working Token Saver
  • The Server Split That Almost Didn't Happen
  • I Opened My First Open Source PRs. None of Them Are Merged Yet.
  • Checking Upstream: What v0.5.50 Gained for 9router
  • The 403 That Wasn't: How Warp, 9router, and Cloudflare Masked Two Separate Failures

Trending Tags

9router technical tooling ade ai personal postmortem warp agents orchestration

Further Reading

Jul 24, 2026

Building Memory Into 9router: A Proxy-Layer Experiment

Every coding AI I tried was great at problems, terrible at context. I’d start a new session and describe my stack, my preferences, my ongoing projects — everything the AI needed to be useful. Next...

Aug 7, 2026

Debugging 9router Headroom: The Silent 404 That Masked a Version Mismatch

I found Headroom in a random LinkedIn post. It looked great — a compression proxy that sits between your app and the LLM providers, strips redundant context, saves tokens. The pitch was compelling....

Jul 31, 2026

The 403 That Wasn't: How Warp, 9router, and Cloudflare Masked Two Separate Failures

My Warp agent stopped talking to 9router. Quick background: 9router is my AI routing layer — a Hono server that proxies LLM requests through fallback providers. It runs locally via a Cloudflare tu...

Older
The Router My Colleague Showed Me
Newer
The Tunnel

© 2026 Alvian. Some rights reserved.

This blog is open source — view on GitHub

Using the Chirpy theme for Jekyll.

Trending Tags

9router technical tooling ade ai personal postmortem warp agents orchestration