The Zenith Routing Engine
How kRouter picks which of your accounts serves a request: Zenith scoring, conversation stickiness, cooldowns, and the round-robin, P2C and random options.
When you connect more than one account of the same provider, kRouter has to pick one for every request. This page explains how. Choosing between models is a different job, done by combos; the strategies here only decide which account serves the model that was chosen.
The default is Zenith
The global setting is under Settings → Routing Strategy. Its default entry is labelled Zenith (versions before v0.5.164 call it Fill First, but it has not filled one account first since v0.5.70). Zenith scores every available account and picks the highest score.
An account's score is built from three things:
- Health. kRouter tracks each account's recent success rate and response time in memory. The health score is the success rate scaled to 1,000, minus a small penalty for latency. Old results fade over a few minutes, so an account that failed briefly recovers on its own. An account with no history yet starts with a neutral score, so new accounts get tried.
- Remaining quota. For providers that report quota, an account with less than 30% left for the requested model has its score scaled down in proportion, to a tenth at most. An account with plenty of quota is not penalised, and neither is one whose provider reports no quota (before v0.5.164 that was scored as no quota left).
- List position. The top account in the list gets 40 points, then 30, 20 and 10 for the next three. That only settles near-ties. Before v0.5.164 this ran the other way (10 points per position down the list), which favoured the bottom account.
Accounts that are cooling down, locked or disabled are removed before scoring, so Zenith only chooses among accounts that can take the request.
The same conversation goes back to the same account
With every strategy except round-robin, later turns of a conversation are sent to the account that served the earlier turns, as long as that account is still available. This keeps the provider's prompt cache warm. If the account has since been rate limited, the turn goes to the next best account.
Other strategies
| Strategy | What it does |
|---|---|
| Zenith (default; Fill First before v0.5.164) | Scores accounts as described above |
| Round Robin | Rotates through accounts. It stays on one account for a number of requests before moving on (the Sticky Limit, default 3), and picks the least recently used account next |
| P2C (power of two choices) | Picks two accounts at random and uses the one with the better Zenith score |
| Random | Picks any available account |
Each provider's page can override the global choice. One provider has a different built-in default: Antigravity uses round-robin unless you set a strategy on its own page, because it enforces per-minute limits per account.
What happens when an account fails
When an account returns an error, kRouter classifies it, puts that account (or that model on that account) on a cooldown, and retries the request on another account of the same provider. Only when none is left does a combo move on to its next model.
- Rate limits start at a 2-second cooldown and back off exponentially to 5 minutes.
- A provider that names its reset time has that model parked on the account until then, 6 hours at most.
- A 429 on an account whose quota data says it has plenty left is treated as a per-minute limit: 90 seconds.
- "Verify your account" and suspended or deactivated accounts lock the whole account for 24 hours. Repeats lock it for longer (2, 4, 7, then 14 times as long), and after three in a row the account shows a chronic ban badge.
- Input-size errors (prompt too long, request too large) are returned to you straight away with no cooldown, because every account would reject the same request.
The full table is in Combos & fallback.
Account state is held in memory, re-synced from SQLite every 10 seconds, so picking an account does not wait on the database. A new cooldown is applied in memory immediately and written to SQLite in the background, so it also survives a restart.
Seeing the decisions
- Each account on a provider's page shows a Z: chip with its current health score. Hover it for the success rate, average latency and number of observed requests.
- The provider page also has a collapsible Routing decisions panel: the most recent routing decisions for that provider, each with the model, the chosen account, its Zenith score, the latency and whether the request succeeded. The log lives in memory and is cleared when kRouter restarts.
- Test Connection One-by-One, in the provider's Connections section, checks every account. A successful test also clears that account's cooldowns and locks, which is how you bring an account back after verifying it with the provider.
Accounts and the provider's terms
Spreading requests across several of your own accounts does not change what a provider allows. Some subscription logins are not licensed for proxy use at all, and the dashboard shows a risk notice before you connect them. See Providers.
Where to go next
- Combos & fallback: choose between models, not accounts
- Architecture: where account choice sits in a request's path
- The Zenith write-up: the design story behind the engine