> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ccs.kaitran.ca/llms.txt
> Use this file to discover all available pages before exploring further.

# Account Pools

> Run several Claude accounts as one pool and auto-continue when an account hits its limit

# Account Pools

An account pool lets you put several Claude accounts behind one provider profile
so a session keeps going when one account hits its rate limit. Instead of seeing
a limit error and switching accounts by hand, the pool moves the conversation to
the next available account for you.

A pool is three things working together:

1. **Several accounts** authenticated under the built-in `claude` CLIProxy
   provider.
2. **One provider profile** you launch with `ccs claude`.
3. **Auto-continue on limit**: when the active account is rate limited, CLIProxy
   hops to the next account in the pool so the turn completes.

<Note>
  Account pools route through your local CLIProxy. They are separate from native
  account profiles (`ccs work`, `ccs personal`). The two systems do not share
  session history. See [When not to pool](#when-not-to-pool) and
  [Migrating from native profiles](#migrating-from-native-profiles).
</Note>

## Terminology

These words get mixed up. Here is what each one means in CCS.

| Term                | Meaning                                                                                                                                                                    |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Account profile** | A native Claude account lane created with `ccs auth create <name>`, run with `ccs <name>`. Has its own `CLAUDE_CONFIG_DIR` and its own session history. Does **not** pool. |
| **OAuth account**   | A single Claude login (one email, one set of tokens). The unit a pool is built from.                                                                                       |
| **Variant**         | A user-defined CLIProxy provider entry under `config.cliproxy.variants` (for example, a custom Codex model variant).                                                       |
| **Provider**        | A CLIProxy backend such as `claude`, `agy`, `gemini`, or `codex`. A pool lives under one provider.                                                                         |
| **Pool**            | Two or more OAuth accounts under one CLIProxy provider with pool routing enabled. Auto-continues on limit.                                                                 |

### Codex has two separate lanes

Codex can confuse you the same way, because the word "pool" shows up in two
different places:

* **CLIProxy Codex pool**: OAuth accounts under the `codex` CLIProxy provider,
  reached with `ccs codex`. This is the pool world described on this page.
* **Native Codex runtime lane**: the `ccsx`, `ccsxp`, and `ccsd` aliases route a
  profile to the native Codex CLI. That is a runtime target, not a CLIProxy
  account pool. See [Codex Adapter](/features/workflow/codex-adapter).

Same two-worlds split as Claude (CLIProxy lane vs native lane), different
provider. When you read "Codex pool" make sure you know which lane is meant.

## Set up a pool in three commands

<Steps>
  <Step title="Authenticate your first account">
    ```bash theme={null}
    ccs claude --auth
    ```

    Opens your browser for Claude OAuth. The token is stored under the built-in
    `claude` CLIProxy provider.
  </Step>

  <Step title="Add more accounts">
    ```bash theme={null}
    ccs claude --auth --add
    ```

    Run this once per extra account. Each `--add` opens a fresh OAuth flow and
    stores the new account alongside the first. For a three-account pool, run it
    twice.

    When you cross from one account to two, CCS offers to turn on pool routing
    for you (interactive terminals only). You can accept there, or enable it
    later with `ccs cliproxy pool --enable`.
  </Step>

  <Step title="Launch the pool">
    ```bash theme={null}
    ccs claude
    ```

    `ccs claude` runs Claude Code through the local CLIProxy with all your
    authenticated accounts behind it. When one account is rate limited, the pool
    continues on the next one.
  </Step>
</Steps>

To confirm pool routing is on:

```bash theme={null}
ccs cliproxy pool
```

## How failover behaves

### Fill-first plus session affinity

Pool routing uses two settings together:

* **fill-first**: drain one account fully before moving to the next, instead of
  spreading requests evenly. This keeps as much of your conversation as possible
  on a single account.
* **session affinity**: pin one conversation to one account (TTL 1h) so a
  multi-turn session stays put until it has to move.

The result: your conversation sticks to one account until that account hits its
limit, then hops.

### A pre-stream limit hops transparently

When the active account is rate limited **before** the response starts
streaming, CLIProxy switches to the next account and the turn completes there.
You do not see an error. The hop is transparent.

### The turn right after a hop is slower

Here is the cost to know about. When the pool hops to a new account, the new
account has none of your conversation cached. The next turn re-processes your
**whole** conversation from the start on the new account.

That means the turn right after a hop is noticeably slower, and the slowdown is
proportional to how large your conversation is. A short conversation re-processes
quickly. A long one (tens of thousands of tokens of context) takes longer,
because the entire context has to be read again on the fresh account.

CCS does not publish a fixed latency number here because it depends on context
size, model load, and provider response time. Treat the first turn after a hop
as a full-context turn, not a warm-cache turn.

This happens once per hop. After the hop, the conversation is cached on the new
account again and turns return to normal speed until the next hop.

## When not to pool

A pool is the right tool when you want one continuous session that survives rate
limits. It is the wrong tool when you want accounts kept apart.

**If you want strict separation between accounts** (work vs personal, separate
billing, separate history), use native account profiles instead:

```bash theme={null}
ccs auth create work
ccs auth create personal

ccs work "review this PR"
ccs personal "help with a side project"
```

Native profiles keep credentials, tokens, and session history isolated per
account. They do not auto-continue across accounts. See
[Claude Accounts](/providers/concepts/claude-accounts).

**Bare `ccs` does not pool.** Running plain `ccs` launches your native default
account lane, not the CLIProxy pool. Pooling only happens when you launch through
`ccs claude` with pool routing enabled. If you want pooled failover, use
`ccs claude`; if you want your single native account, use `ccs`.

## Leaving a pool

To turn pool routing off, use the disable command. Do not hand-edit routing back
to plain round-robin (see the warning below).

```bash theme={null}
ccs cliproxy pool --disable
```

This regenerates the CLIProxy config with cooling disabled (stability mode) and
restores your original routing settings. The exact output:

```
[OK] Pool routing disabled. CLIProxy config regenerated with cooling disabled (stability mode).
    Your original routing settings are restored.
    If you have multiple accounts and want fair distribution, round-robin is active.
    To avoid cache-burn with large multi-account fleets, consider reducing to 1 account
    or re-enabling pool routing: ccs cliproxy pool --enable
```

### Why not just switch to round-robin

It is tempting to "leave the pool" by setting routing to plain round-robin with
no session affinity. Do not do this with a multi-account fleet.

Round-robin with no affinity spreads each request across accounts. Without
affinity, consecutive turns of the same conversation land on different accounts,
and each landing re-processes your whole conversation on a cold account. That is
the cache-burn footgun: you pay the full context-recompute cost on most turns,
not just on a hop.

`ccs cliproxy pool --disable` avoids this. It restores a safe non-pool config
(cooling disabled, your original routing), instead of leaving you in the
worst-case round-robin-no-affinity state.

## Migrating from native profiles

If you already run native account profiles (`ccs work`, `ccs personal`) and want
to pool those same accounts, read this first. The two lanes do not share
credentials or history.

### You re-authenticate each account fresh

You cannot import credentials from a native profile into the pool. A native
profile's refresh token is bound to a different OAuth client, so the pool cannot
reuse it. To pool an account you already use natively, authenticate it again
under the `claude` CLIProxy provider:

```bash theme={null}
ccs claude --auth          # first account, fresh OAuth
ccs claude --auth --add    # each additional account, fresh OAuth
```

Same Claude login, new OAuth grant. This is required, not optional.

### Session history does not follow

Pooled sessions live in the CLIProxy lane. Your native profile's session history
and your `--continue` / resume inventory stay in the native lane. They do **not**
move into the pool. After migrating, a pooled `ccs claude` session starts with a
clean history; your old `ccs work` transcripts remain reachable only through
`ccs work`.

### Pause the native profile for the same account

Once an account is in the pool, do not keep launching the same account through
its native profile at the same time. Running one Claude account in two lanes
concurrently (native profile in one terminal, pool in another) is the one
behavior that raises account risk. See [Safety notes](#safety-notes).

To avoid it, pick one lane per account. If you migrate an account into the pool,
stop using its native profile for live sessions, or remove the native profile so
there is no second lane to launch by accident.

## Caveats

Read these before you rely on a pool.

### Mid-stream errors do not re-route

The transparent hop only applies when a limit is hit **before** the response
starts streaming. If an account fails **after** the first chunks have already
streamed, that turn is not re-routed: you see a visible error for that turn. The
pool hops on the **next** turn, not retroactively.

The exact visible error text can vary by Claude Code version and provider
response, so the important rule is timing: after chunks start streaming, CCS
cannot rewind and replay that same turn on a different account.

### All accounts cooling vs a paused account

These are two different failure states with two different errors:

* **All accounts cooling**: every account in the pool is rate limited at once.
  You get a 429 with a reset time telling you when the soonest account frees up.
* **A paused account**: the only candidate is paused (for example, after a ban
  pattern auto-pause), which surfaces as a different error, not a 429-with-reset.

Use `ccs cliproxy quota` to tell them apart. Cooling accounts show
`cooling until <time>` when CCS can see a reset time; paused accounts show
`paused (manual or safety)` and include a resume hint.

### One context recompute per hop

Every hop pays one full context recompute on the new account, which costs both
quota (the re-read tokens) and latency (the slower turn described in
[How failover behaves](#the-turn-right-after-a-hop-is-slower)). Pools minimize
hops with fill-first plus affinity, but a hop is never free.

### Remote and Docker pools need manual config

On a remote or Docker CLIProxy, CCS cannot manage the pool the same way it does
locally:

* The interactive opt-in prompt is not shown.
* Session affinity is not remotely toggleable from CCS.
* You must configure pool routing in the remote CLIProxy `config.yaml` by hand.

If you run multiple accounts on a remote CLIProxy **without** pool config, you
get round-robin with no affinity, which is the cache-burn state described under
[Leaving a pool](#why-not-just-switch-to-round-robin). To enable pool routing
manually on a remote target, add to the CLIProxy `config.yaml`:

```yaml theme={null}
disable-cooling: false
max-retry-credentials: 3
routing:
  strategy: fill-first
  session-affinity: true
  session-affinity-ttl: "1h"
```

### Claude quota percentages are limited

Claude OAuth does not expose full quota percentages to CCS the way some other
providers do (the underlying signal is `policy_quota_unsupported`). You will see
limit and reset behavior, but not a precise "N% remaining" figure for Claude
pool accounts.

### Claude tier detection is unavailable

CCS cannot detect the subscription tier (Pro vs Max) of a Claude pool account.
Tier-based drain ordering (`--by-tier`) is available for providers that report
tier (`agy`, `gemini`), but not for `claude`. For Claude, the pool drains in
file order, or in an order you set manually with
`ccs cliproxy accounts order claude --set`.

## Safety notes

Pool routing ships with guardrails on by default:

* **Cooldowns are honored.** A rate-limited (429) account is suspended briefly
  with exponential backoff (1s up to 30m). A broken-auth account (401/403) is
  suspended for 30 minutes, because broken auth should not keep taking traffic.
* **Retry cap.** A single request stops after `max-retry-credentials: 3`
  attempts across accounts instead of walking the entire fleet.
* **Ban-pattern auto-pause.** If an account shows a ban signal, CCS pauses it out
  of rotation automatically.

### The honest version of account risk

Pools do **not** add a new ban vector. Running accounts behind one local CLIProxy
is the same traffic shape Anthropic already sees from a single client.

The risk that **does** exist is concurrency: the same Claude account active in
two clients or two lanes at once. A pool by itself does not create this, because
the pool drains one account at a time with affinity. But **migration can create
it** if you keep an active native profile for an account you have also added to
the pool. Then you can launch that one account twice (native lane plus pool lane)
and run it concurrently.

The fix is in [Migrating from native profiles](#pause-the-native-profile-for-the-same-account):
pick one lane per account. Pool the account, or run it natively, but not both at
the same time.

## Related commands

| Command                                          | What it does                                                      |
| ------------------------------------------------ | ----------------------------------------------------------------- |
| `ccs cliproxy pool`                              | Show pool routing status                                          |
| `ccs cliproxy pool --enable`                     | Enable pool routing (fill-first, affinity, cooling on, retry cap) |
| `ccs cliproxy pool --disable`                    | Disable pool routing and restore a safe non-pool config           |
| `ccs cliproxy accounts order claude`             | Show the order accounts drain in                                  |
| `ccs cliproxy accounts order claude --set <ids>` | Set a manual drain order                                          |

See the [CLI reference](/reference/cli-commands#cliproxy-management) for the full
command surface.

## Next steps

<CardGroup cols={2}>
  <Card title="Claude Accounts" icon="users" href="/providers/concepts/claude-accounts">
    Native account profiles when you want accounts kept separate
  </Card>

  <Card title="Claude Provider" icon="robot" href="/providers/oauth/claude">
    OAuth, multi-account, and quota details for the claude provider
  </Card>

  <Card title="Multi-Account Setup" icon="users-gear" href="/tutorials/multi-account-setup">
    Step-by-step account setup across providers
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/reference/cli-commands">
    Full pool, routing, and account command surface
  </Card>
</CardGroup>
