Agent infrastructure
claude-swap — agent quota infrastructure
A pure-Go daemon and reverse proxy that keeps a fleet of AI coding agents fueled by hot-swapping OAuth credentials and load-balancing sessions across subscription quota windows.
Go · reverse engineering · reverse proxy · load balancing · OAuth
claude-swap is the fuel-supply layer beneath a large fleet of AI coding agents. Claude Code subscriptions come with rolling quota windows that reset on a schedule and never roll over — quota is a perishable commodity — but the CLI only authenticates as one account at a time. claude-swap turns “which account should be burning right now” into a small, legible control-systems problem: a ~12,000-line pure-Go daemon and reverse proxy that monitors every account’s remaining quota, hot-swaps credentials before a window exhausts, and load-balances live sessions so nothing is wasted and no account gets overworked.
The foundation is reverse engineering. None of the endpoints the system depends on are documented, so the design was locked and live-validated a day before the first commit — including the keystone discovery of a usage endpoint that reports remaining quota without spending any, and the empirical fact that writing a credential blob to disk is enough for running sessions to pick it up with no restart. Refresh tokens turned out to be one-time-use and rotate on every refresh, which forced a careful ownership protocol so two cooperating processes never race on the same token.
The hardest problem is deciding under a vanishing signal: the usage endpoint rate-limits hardest exactly when the fleet is busiest. The daemon answers with watermarks and hysteresis, a burn estimator that infers consumption from recent token throughput when fresh readings are unavailable, and a blind-bail limit that caps how long it will ride an account without data. When flipping a single shared credential started thundering-herd cascades of rate-limit errors, a second mode was added: a reverse proxy that pins each session to one account — preserving its prompt cache — and drains a saturated account gracefully, one session at a time.
Today it runs as a systemd and launchd service plus a shared proxy served over a tailnet behind HTTPS, all in a ~10 MB static binary under a 64 MB memory cap. It also produces data: a per-model, per-account priced cost report backed by a SQLite time-series store (which retired a separate 992-line TypeScript reporting tool downstream), and an asynchronous full-transcript capture pipeline — auth headers never persisted — that turns fleet traffic into a corpus for offline analysis.