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

  • Building Memory Into 9router: A Proxy-Layer Experiment
  • The Tunnel
  • This Is My ADE
  • Why I Left GitHub Copilot
  • The Router My Colleague Showed Me

Trending Tags

9router tooling technical personal ai warp ade analytics postmortem agents

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...

Jul 8, 2026

This Is My ADE

I hit send on a prompt. Watched the spinner. Started calculating — was I past the cap yet? Three weeks into the billing cycle, OpenCode Go had hit its limit. I’d been conditioned to expect the erro...

Jun 10, 2026

The Router My Colleague Showed Me

I first noticed it in passing. Colleagues had it open during work — a dashboard I didn’t recognize, a dropdown with more providers than I’d ever seen. I didn’t ask right away. Just filed it away as...

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 tooling technical personal ai warp ade analytics postmortem agents