Profile
Back to NewsBack
GitHub Trending 7 min
Reader Mode
luqman-v1/9router-go: High-performance Go proxy gateway for 9Router LLM routing — 32K RPS, 42MB RAM, CGO-free

luqman-v1/9router-go: High-performance Go proxy gateway for 9Router LLM routing — 32K RPS, 42MB RAM, CGO-free

14 hours ago

9router-go — FREE AI Router & Token Saver (Single Binary)

Never stop coding. Save 20-40% tokens with RTK + auto-fallback to FREE & cheap AI models.

Connect Claude Code, Cursor, Antigravity, Codex, Gemini, OpenCode, Cline, OpenClaw... to 40+ AI providers & 100+ models — no Node.js needed at runtime.

CI</a> Release</a> GitHub release</a> License</a>

🚀 Quick Start • 💡 Features • ⚙️ Setup • 🌐 Upstream


🤔 Why 9router-go?

Same idea as 9Router, minus the Node.js runtime: one Go binary serves the proxy APIs + an embedded Svelte dashboard.

Stop wasting money, tokens and hitting limits:

  • ❌ Subscription quota expires unused every month
  • ❌ Rate limits stop you mid-coding
  • ❌ Tool outputs (git diff, grep, ls...) burn tokens fast
  • ❌ Manual switching between providers
9router-go solves this:
  • ✅ RTK Token Saver — auto-compress tool_result content, save 20-40% tokens
  • ✅ Auto fallback — Subscription → Cheap → Free, zero downtime
  • ✅ Multi-account — round-robin between accounts per provider
  • ✅ Single binary — Go + embedded dashboard, works with Claude Code, Codex, Cursor, Cline, any CLI tool

🔄 How It Works

┌─────────────┐
│  Your CLI   │  (Claude Code, Codex, OpenClaw, Cursor, Cline...)
│   Tool      │
└──────┬──────┘
       │ http://localhost:20130/v1
       ↓
┌─────────────────────────────────────────────┐
│         9router-go (Smart Router)           │
│  • RTK Token Saver (cut tool_result tokens) │
│  • Format translation (OpenAI ↔ Claude)     │
│  • Quota tracking                           │
│  • Auto token refresh                       │
└──────┬──────────────────────────────────────┘
       │
       ├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, GitHub Copilot
       │   ↓ quota exhausted
       ├─→ [Tier 2: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M)
       │   ↓ budget limit
       └─→ [Tier 3: FREE] Kiro, OpenCode Free, Vertex ($300 credits)

Result: Never stop coding, minimal cost + 20-40% token savings via RTK


⚡ Quick Start

1. Install (one line):

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/luqman-v1/9router-go/main/install.sh | bash
# Windows (PowerShell, no admin needed)
irm https://raw.githubusercontent.com/luqman-v1/9router-go/main/install.ps1 | iex

🎉 Then start it (defaults: port 20130, data ~/.9router — no flags needed):

9router-go

Dashboard: http://localhost:20130 (Default password: 123456)

Already use upstream 9Router? Point Go at the same data dir — it opens the same DATA_DIR/db/data.sqlite: providers, connections, combos, and usage carry over. Details in DATABASE.md.

Keep the terminal free (background mode):

9router-go start          # same as: 9router-go --background   (or -d)
9router-go status         # is it running? (pid, dashboard, log)
9router-go restart        # replace the running daemon
9router-go logs -n 100    # tail the background log
9router-go stop           # stop it

The detached process records itself in DATA_DIR/run/gateway.pid and writes its output to DATA_DIR/run/gateway.log. A second start while one is running refuses instead of fighting over the port, and a daemon killed from Task Manager leaves nothing behind: the stale pid file is cleaned on the next command.

Windows stops the process with TerminateProcess instead of SIGTERM, so
stopping skips the graceful drain; use the dashboard's Shutdown button or
9router-go restart when you want in-flight streams to finish first.

2. Connect a FREE provider (no signup needed):

Dashboard → Providers → Connect Kiro AI (~50 credits/month free) or OpenCode Free (no auth) → Done!

3. Use in your CLI tool:

Claude Code / Codex / OpenClaw / Cursor / Cline Settings:
  Endpoint: http://localhost:20130/v1
  API Key:  [Settings → API Keys in the dashboard]
  Model:    kr/claude-sonnet-4.5

That's it! Start coding with FREE AI models.

Alternatives:

# Docker — no build needed
docker run -d --name 9router-go --restart unless-stopped \
  -p 20130:20130 -v "$HOME/.9router:/data" \
  -e PORT=20130 -e DATA_DIR=/data \
  -e INITIAL_PASSWORD=your-secure-password \
  luqmenul/9router-go:latest

Manual download — pick your file, no command line guesswork:

Windows → .exe | Mac M1+ → darwin-arm64 | Mac Intel → darwin-amd64

Linux VPS → linux-amd64 | Raspberry Pi → linux-arm64

📦 All release binaries • 🔨 Build from source


💡 Key Features

  • 🖥️ Native Svelte 5 dashboard: providers, OAuth, combos, proxy pools, API keys, usage, quota, settings
  • 🔌 OpenAI Chat, Claude Messages, Gemini, Ollama-compatible, Responses, embeddings, media, search, web tools
  • 🔁 Combos with fallback, round-robin, sticky routing, fusion, capability-aware reordering
  • 👥 Per-provider executors, OAuth refresh, reactive 401 retry
  • 📡 Live usage + console-log SSE streams, stall detection
  • 💾 SQLite WAL persistence, outbound proxy support, self-update, MITM commands, Docker, cross-compilation

⚙️ Setup Guide

Release binary

Download from GitHub Releases, verify against SHA256SUMS.txt.

Build from source

Prerequisites: Go 1.27 and Bun 1.x (dashboard is embedded into the binary, so build web first):

git clone https://github.com/luqman-v1/9router-go.git
cd 9router-go
make web-build   # bun install --frozen-lockfile && bun run build
make build       # embeds VERSION into the Go binary

Run

Defaults are enough for most people — plain 9router-go listens on port 20130 with data in ~/.9router:

9router-go
curl http://localhost:20130/health
./9router-go version

Only override when you need something different (PORT, DATA_DIR/DB_PATH — there are no --port flags):

PORT=20129 ./9router-go                        # different port
DATA_DIR=/srv/9router ./9router-go              # different data dir
DB_PATH=/srv/9router/data.sqlite ./9router-go   # explicit SQLite file
HOST=127.0.0.1 ./9router-go                     # localhost only, behind a reverse proxy

🔑 Dashboard Login & Fresh Install

  • Localhost (localhost / 127.0.0.1): First login uses the default compatibility password 123456. Once logged in, change your password in Settings → Profile.
  • Remote / VPS / Docker / LAN: For security (preventing public takeover of fresh installs with known defaults, CVE-2026-56679), remote access blocks the default 123456 password. You must either:
1. Set INITIAL_PASSWORD on launch (Recommended):
INITIAL_PASSWORD="your-secure-password" ./9router-go
     # Or in your .env file:
     # INITIAL_PASSWORD=your-secure-password
2. Or access via SSH port-forwarding first:
ssh -L 20130:127.0.0.1:20130 user@remote-host
     # Open http://localhost:20130, login with 123456, then change password in Settings

Client example

curl http://localhost:20130/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer sk-your-api-key' \
  -d '{"model":"ag/gemini-3.8-flash-high","messages":[{"role":"user","content":"Hello"}],"stream":true}'

For Claude Messages clients: ANTHROPIC_BASE_URL=http://localhost:20130/v1.

Advanced: environment variables, API surface, auth, database

Environment

| Variable | Default | Purpose | | --- | --- | --- | | PORT | 20130 | HTTP port | | HOST / BIND_ADDR | all interfaces | Listener address | | DATA_DIR | ~/.9router (%APPDATA%/9router on Windows) | Data root | | DB_PATH | $DATA_DIR/db/data.sqlite | SQLite file | | INITIAL_PASSWORD | unset (fallback 123456 locally) | First dashboard password | | RTK_ENABLED | true | RTK input compression | | CAVEMAN_ENABLED / PONYTAIL_ENABLED | false | Style savers | | AUTO_UPDATE | false | Background self-update | | HTTP_PROXY / HTTPS_PROXY | Go defaults | Upstream egress proxy | | PPROF_ENABLED | false | Expose /debug/pprof/* (keep off on untrusted networks) | | TRUST_PROXY / TRUST_CLOUDFLARE | unset | Trust forwarded client-IP headers |

.env.example documents the security-sensitive subset and OAuth overrides.

API surface

POST /v1/chat/completions       OpenAI Chat Completions
POST /v1/messages               Claude Messages
POST /v1/responses              Responses API
POST /v1/embeddings             Embeddings
POST /api/chat                  Ollama-compatible chat
GET  /v1/models                 Model catalog
POST /v1/images/generations     Image generation
POST /v1/videos/generations     Video generation
POST /v1/audio/speech           Text to speech
POST /v1/audio/transcriptions   Speech to text
POST /v1/search                 Web search
GET  /api/usage/stream          Live usage SSE
GET  /health                    Liveness
GET  /api/version               Version metadata

Authentication

  • Public: /health, dashboard HTML/assets, /login, OAuth callbacks.
  • Proxy routes need an active client API key (Authorization: Bearer / X-API-Key).
  • Dashboard APIs need a session cookie, CLI token, or API key; destructive ops (shutdown, update, DB import) need a session or CLI token.
  • The API server defaults to all interfaces — bind localhost or protect the port outside trusted machines.

Database compatibility

Go reads/writes the upstream 9router table/JSON shapes and bootstraps the core schema on startup (creates the 11 tables when absent, backfills missing columns, seeds an empty settings row) — a fresh DATA_DIR just works, no upstream install needed. Existing databases are never modified beyond additive backfills. Full contract in DATABASE.md, routing internals in ARCHITECTURE.md.


📚 Docs

  • ARCHITECTURE.md — routing, providers, runtime layout
  • DATABASE.md — SQLite schema & operator contract
  • ROADMAP.md — proposals only, not current behavior
  • CHANGELOG.md — release history (Go v1.9.6, upstream baseline decolua/9router v0.5.85)

Credits

  • 9Router — original Next.js gateway & dashboard this Go port preserves compatibility with
Chat with me