Multiple Claude accounts (usage routing)
Sparkle lets you stack more than one Claude Code Max subscription and routes every agent to the account with the most headroom. When one plan hits its limit, the job moves to another automatically, so a full fleet keeps building instead of stalling on a single account's weekly cap.
What it is
Each account is its own isolated Claude config directory that you log into with the normal Claude browser sign-in. Sparkle owns the folder, never your credentials. Before an agent starts, Sparkle picks which account it runs under; when an account taps out, Sparkle fails over to one with room left.
Think of a Claude Code Max subscription as your monthly allowance of AI building power. Every plan (Claude Pro, Claude Max 5x, Claude Max 20x) gives you a set amount of usage before you have to wait for it to refill. If you are running several helpers at once, one allowance can run dry partway through the day, and everything pauses.
Sparkle fixes that by letting you add more than one Claude account. You log into each one exactly the way you already do (a normal Claude sign-in in your browser, no special keys, no copying secrets anywhere). Sparkle keeps each login in its own private folder and quietly hands each helper to whichever account has the most allowance left. You do not have to think about any of it. You just keep building, and Sparkle handles the juggling.
Running a fleet on one plan means you eventually hit the weekly cap mid-sprint and everything grinds to a halt. Stacking plans is the fix: add a second or third Claude Code Max subscription and Sparkle load-balances across all of them.
The leverage is obvious once you feel it. More accounts means more usage means more parallel agents sustained for longer, without you babysitting a balance. Sign into each account once, then forget about it: Sparkle routes each new agent to the account with the lowest recent usage and reroutes the moment one gets rate-limited. You spend your attention on the build, not on which plan still has gas in the tank.
Multiple accounts, each an isolated CLAUDE_CONFIG_DIR you authenticate with a
standard claude login. The imported ~/.claude is the default account and
cannot be removed. Sparkle stores per-account metadata (nickname, config dir)
and reads windowed token tallies from each account's own transcripts. No
credentials pass through Sparkle: it owns the folder, the OS owns the auth.
The point is sustained throughput. A single subscription's 7-day window is a hard ceiling on a parallel fleet; stacking N subscriptions multiplies the ceiling and lets the scheduler keep N lanes saturated instead of serializing behind one cap.
How it works
Sparkle makes the routing decision at spawn time, per agent, and revises it reactively when an account hits a real limit.
Two simple things happen behind the scenes. First, every time a new helper starts, Sparkle looks at how much each of your accounts has been used recently and gives the new helper the account that has been used the least. That spreads the work out evenly so no single account drains first.
Second, if a helper ever runs into a "you have hit your limit" message, Sparkle notices, sets that account aside until it refills, and sends the next job to a different account that still has room. It is like having several gift cards and always reaching for the one with the most money left, then putting an empty one back in your wallet until it tops up again.
Here is the routing logic worth knowing:
- Selection. When an agent spawns, Sparkle picks the account with the lowest 7-day usage, breaking ties on the lowest 5-hour usage. Accounts that are rate-limited or near a window cap are skipped.
- Failover. When a running agent prints a real rate-limit message, Sparkle benches that account until its limit resets and routes the next job elsewhere. If it can read a reset time from the message it uses that; otherwise it backs off a few hours and brings the account back into rotation later.
- Headroom-first. A brand-new account with no usage yet is treated as having the most room, so it gets picked first. The rotation self-balances from there.
You do not configure any of this. Add accounts, sign in, and the scheduler does the rest.
Mechanics, source-accurate:
pickAccountranks candidates by lowesttokens7d, tie-break lowesttokens5h. It first filters out accounts whoseexhaustedUntilis in the future or that are at/above a soft window cap, then reduces to the minimum. An account with no usage row is treated as zero (maximum headroom). If every account is excluded it falls back to the default rather than blocking the spawn: the hard rate-limit is the real backstop.- Failover is best-effort PTY scraping. A conservative regex matches Claude's
limit phrasing (
rate limit,usage limit,limit reached,too many requests); on a hit it callsmarkExhaustedwith a parsed reset time, or a 4-hour default backoff when no unambiguous "resets at H[:MM] am/pm" is present. The match is deliberately narrow so an agent printing "the cache resets at 9am" never benches a healthy account. - The chosen account's config dir is passed as
CLAUDE_CONFIG_DIRfor that spawn. With no accounts registered, the env var is omitted and behavior is exactly as before accounts existed.
This is Phase 1: text-scrape detection, static-by-default ceilings, in-memory pins. The hard limit corrects a bad usage estimate, which is why conservative detection is acceptable.
Pinning an agent to an account
Automatic routing is the default, but you can override it. Pin any agent to a specific account and every future spawn for that agent uses it.
Most of the time you want Sparkle to choose for you. But sometimes you want a particular helper to always use a particular account (maybe one account is your big plan and you want your most important build on it). You can "pin" a helper to an account, and from then on it always uses that one. Unpin it whenever you want to hand the choice back to Sparkle.
Pin when you want control: a long-running orchestrator on your Max 20x, a throwaway experiment on a smaller plan. A pin wins unconditionally, so the pinned agent stays put regardless of usage. Clear the pin to drop the agent back into automatic lowest-usage routing.
The per-agent pin is a manual override that beats the ranking entirely: a valid
pinnedAccountId is returned outright, even if that account is exhausted or near
cap, because a human chose it on purpose. Pins are an in-memory map
(agentId to accountId) in Phase 1 and reset on app restart.
Your credentials stay yours
This is the part to feel good about: adding accounts does not mean handing Sparkle your passwords. You sign into each Claude account the same way you always do, in your browser, and the login lives in a private folder on your own Mac. Sparkle just remembers which folder to point each helper at. Nothing sensitive is copied, uploaded, or shared.
No keys to paste, no secrets to manage. Each account is a standard Claude login in its own config dir on your machine. Sparkle routes by pointing the Claude Code process at the right directory, so your auth never leaves your Mac and never passes through Sparkle.
Each account is a discrete config dir authenticated by a standard claude login;
Sparkle sets it as CLAUDE_CONFIG_DIR per spawn and stores only metadata. The
credential material lives where Claude Code puts it, on disk, under your user.
Sparkle is a router, not a credential broker.
vs. the 1980s terminal
A terminal has no concept of an account, a usage balance, or headroom. It
runs whatever you launch against whatever login happens to be active, with no
awareness that you might have several, no way to compare their remaining usage,
and no way to fail over when one is throttled. You would be manually swapping
CLAUDE_CONFIG_DIR, watching for limit messages by eye, and restarting jobs by
hand. Sparkle makes the choice, watches for the limits, and reroutes for you.