Skip to main content
kRouter
All posts
How kRouter works

Multiple accounts per provider: how kRouter rotates them

Connect several accounts of one provider and kRouter picks one per request: Zenith scoring, round-robin, cooldowns, concurrency caps, and the terms risk.

Kodelyth · The team behind kRouter
· Updated
7 min read

Most AI plans cap usage per account: a per-minute token limit, a five-hour window, a weekly or monthly allowance. You usually find the cap mid-task, when your tool gets a 429 and the agent loop stops.

kRouter lets you connect more than one account of the same provider and picks one for each request. When an account is rate limited or out of quota, it sits out and the next request goes to another. This post covers how that choice is made, what happens when an account fails, and where the approach stops helping -- including provider terms, which matter more than any of the mechanics.

An earlier version of this post promised you would "never hit a rate limit again", gave a made-up scoring formula, and suggested stacking free credits across several Google accounts. All three were wrong and have been removed. What follows matches kRouter v0.5.166.

Adding a second account

Open the provider's page in the dashboard, connect the first account, then add another connection from the same page. OAuth providers show a sign-in page or a device code again; API-key providers ask for another key.

Each connection keeps its own tokens, quota and error state, but your tools see one provider. cc/claude-sonnet-4-6 can be served by any of your Claude Code connections.

How kRouter picks an account

The strategy is a global setting under Settings. Each provider's page also has a Round Robin toggle that overrides the global choice for that provider.

The default: Zenith

Settings labels the default Zenith (default). Until v0.5.164 the same option read "Fill First" and the text under it described a fixed priority order; it has run Zenith scoring since v0.5.70. For each request, kRouter scores every available account and takes the highest:

  • Health. Success rate times 1000, minus the recent average latency in milliseconds divided by 100. A fast account with no recent failures scores close to 1000. The counts decay with a five-minute half-life, so one bad stretch is forgotten.
  • Quota. When the provider reports quota and an account has less than 30% left, its score is scaled down in proportion, to a floor of one tenth. An account the provider reports no quota for -- which is most API-key accounts -- is not scaled down at all. Until v0.5.164 it was scored as though it had none left, which cost it nine tenths of its score.
  • List position. The first four accounts on the provider's page add 40, 30, 20 and 10 points, and nothing below that. Against a score near a thousand this only settles near-ties. Until v0.5.164 the bonus ran the other way round, and together with the quota bug above that was enough to send most traffic to the last account in the list.
  • New accounts start near the top, around 970: an account kRouter has not served a request for yet is credited with a short clean history -- five successes, no failures -- and an assumed three-second latency. It gets tried from the start instead of being starved by accounts with a long record, and the same five-minute decay pulls an idle account back towards that baseline.

The effect: healthy accounts with headroom are preferred, and one that is nearly drained drops down the ranking before it starts returning 429s. Each provider's page shows the current ranking and a log of recent routing decisions. The routing engine docs go into more detail.

Round-robin (sticky)

Rotates through accounts, but stays on one for a set number of calls first -- 3 by default, the Sticky Limit in Settings or Sticky on a provider's page. When it moves, it moves to the least recently used account.

It is sticky by call count, not by conversation. A long agent session will move between accounts. That has a cost on some providers: Anthropic, for example, never shares prompt caches between organizations, so a session that lands on another account starts with a cold cache.

P2C and Random

P2C (power of two choices) picks two accounts at random and uses the one with the higher Zenith score. It spreads load more evenly than plain Zenith, which keeps choosing the single best account. Random picks uniformly and is mostly useful for testing.

Antigravity is the one exception to the global setting: unless you choose a strategy for it, it uses round-robin, because its per-minute limit trips quickly when a single account takes a burst.

What happens when an account fails

kRouter keeps the active connections and their locks in memory. When a request fails, the account is locked in memory at once, so the very next request skips it, and the database write happens in the background. Locks are stored, so a restart does not put a blocked account straight back into rotation. Health scores are not stored; they rebuild from traffic after a restart.

How long an account sits out depends on the error. The first row that matches decides:

What happenedCooldown
GitHub Copilot's monthly premium requests used upWhole account held until the next month
Anthropic's monthly spend cap, or a spend limit you set yourselfWhole account held until the date the message names, or 00:00 UTC on the 1st of next month (v0.5.164)
OpenRouter's free-model daily capThat model on that account until the reset OpenRouter names, or 00:00 UTC. Paid models on the same key keep working (v0.5.164)
The provider names an exact reset timeThat model is parked on that account until then, 6 hours at most. Since v0.5.166 this outranks the 90-second reading below
Codex refuses a model the account's ChatGPT plan cannot useThat model on that account, 30 minutes (v0.5.166). Any other Codex 400 is request-scoped, like the 4xx row below
No free concurrency slot on the account (see below)That model, 2 seconds doubling (v0.5.166)
"Verify your account", suspended, deactivatedWhole account locked for 24 hours, longer each time it happens again -- and it stays out of rotation after that until a Test connection succeeds
Kiro's monthly limitWhole account locked for about 30 days
Prompt too longNo cooldown; returned to you at once, since every account would reject it
429, "rate limit", "too many requests", "quota exceeded", "overloaded"That model, exponential backoff from 2 seconds doubling up to 5 minutes
...except when that 429 brought no reset time and the cached quota for that model still looks healthyRead as the per-minute window instead: that model, 90 seconds
401, 402, 403 or 404 with no more specific matchThat model, 2 minutes
Any other 4xx: a malformed body, an unsupported parameter, a failed validationNo cooldown, and no other account is tried -- the request is the problem, not the account. A combo still advances to its next model, which may accept it (v0.5.166)
Any other error, including 500, 502, 503 and 504That model, 30 seconds

When two requests hit a 429 on the same account at the same moment, the backoff level is read and updated inside one database transaction, so both failures count and the cooldown does not come out shorter than it should. That matters because hammering a throttled account is exactly the pattern providers notice. The full error table is in the combos docs.

Per-account concurrency caps

Some plans limit how many requests can be in flight on one account. kRouter caps this per account for the providers where it matters:

ProviderRequests in flight per account
Claude Code5
Kiro4
Codex3
Antigravity, Gemini CLI, Qoder2
OpenCode Free, MiMo Code Free1

Other providers have no cap unless you set one: edit a connection and fill in Max Concurrency. Requests over the cap wait in a short queue. If no slot frees up in time (5 seconds for Antigravity, 15 for Claude Code and Codex, 20 for Kiro, 10 for the rest), kRouter answers itself with a 503 and tries another account. The busy account is skipped for half the time it just waited, at least 2 seconds, and the model it was asked for gets a 2-second cooldown that doubles if it keeps happening. Until v0.5.166 that case fell through to the 30-second default instead, so one IDE fanning out parallel requests could park every account for half a minute over slots that free up in seconds.

Accounts and combos do different jobs

Several accounts answer "same model, another account". When every account of a provider is cooling down, you need another model, and that is what a combo is for:

Combo "always-on"
  1. cc/claude-sonnet-4-6     Zenith picks among your Claude Code accounts
  2. glm/glm-5.3              API key, used once those are all cooling down

Your tool calls the combo name as if it were a model.

What about provider terms?

This is the part to read twice.

  • kRouter warns you itself. Claude Code, Codex, GitHub Copilot, Antigravity, Kiro, Gemini CLI and Qoder are connected through subscription or OAuth sessions that are not licensed for proxy or router use. The dashboard shows a risk notice and asks you to confirm before connecting: the account may be restricted or banned.
  • More accounts does not mean more allowance. Many providers tie a free tier or a subscription to one person, and creating extra accounts to get around a limit is what their terms typically forbid. Spreading requests across your accounts does not change what a provider allows.
  • A ban costs more than quota. If an account gets flagged, you lose the account, not just today's allowance. Antigravity's "verify your account" bans are the common example.

Several accounts make sense when they are legitimately yours -- separate API keys you pay for, or accounts you would hold anyway. Read each provider's terms before you add a second one.

Pointing your tools at it

Your tools do not know any of this exists. They send requests to kRouter, and requests from the same machine need no key unless you set REQUIRE_API_KEY=true:

OPENAI_BASE_URL=http://localhost:20128/v1
OPENAI_API_KEY=any-placeholder

From another machine you need a real key, created on the Endpoint page of the dashboard.

Common questions

Do more accounts raise my rate limit?

Each account keeps its own limits, so spreading requests across several gives you more headroom than one account alone. No single account's limit changes, and neither do the provider's terms.

Does round-robin keep a conversation on one account?

No. It stays on an account for a number of calls (3 by default), then moves on, whatever conversation those calls belong to. On providers that cache prompts per account, each move can mean a cold cache.

Does the default strategy use a fixed priority order?

No. Settings labels it Zenith (default), and it scores each account on health, latency and remaining quota, plus a small bonus for the first four positions in your list. Releases before v0.5.164 labelled the same option "Fill First" and described a fixed order, which it has not been since v0.5.70.

What happens to cooldowns when kRouter restarts?

They survive. Locks and cooldowns are stored in kRouter's database, so a blocked account stays out until its cooldown ends. The health scores Zenith uses are kept in memory and rebuild from new traffic.

Will a second API key on the same account help?

No. Limits are enforced per account (or organization), not per key, so a second key on the same account draws from the same pool.

Kodelyth · The team behind kRouter

Published by Kodelyth, the team that builds kRouter. Posts are drafted with AI assistance and reviewed by a person before they go out. kRouter is free and MIT licensed.

Install kRouter