Run many Claude Code sessions in parallel against one shared task queue. How many actually start comes from the work and from what your computer can spare — a hundred tasks never means a hundred browser tabs.
The problem
Hand a naive runner a list of a hundred pages to process and it will try to open a hundred sessions: a hundred browser tabs, a hundred model contexts, one host hit a hundred times at once. The machine swaps, the site rate-limits you, and half the work is duplicated because two workers grabbed the same item.
agent-fleet is the small amount of machinery that fixes exactly those failures — and nothing else. It is a queue, a planner, and a worker protocol. No daemon, no broker, no database.
rename(2)The mechanism
The planner reads the queue and the machine. Workers are a pool, not a partition: each one claims the next item as it finishes, so the queue length never decides how much is open at once.
Capacity
Concurrency is never taken from the queue length. It is the minimum of what there is to do, what you asked for, what the hosts will tolerate, and what the machine can spare right now — re-read on every run, because the machine's answer changes.
Memory is measured from /proc/meminfo, not guessed, and a container's
memory.max is honoured when present — the host's RAM is not yours to spend.
If nothing fits, capacity floors at one worker and says so, rather than
refusing the run or thrashing the machine.
| Situation | Queue | Free RAM | Workers | Why |
|---|---|---|---|---|
| Workstation, idle | 100 | 10.2 GB | 9 | memory-bound: 900 MB per worker after the reserve |
| Same box, busy | 100 | 2.1 GB | 1 | degrades to serial and prints “one at a time” |
| All on one host | 40 | 10.2 GB | 1 | one worker per host — a rate-limit ban is not throughput |
| Small VM, 2 GB cap | 30 | 1.6 GB | 1 | cgroup limit read and respected |
| You insist | 100 | 2.1 GB | 6 | --force — the only way past the ceiling |
machine: 20 cores, load 3.29, 10.1 GB free → room for 9 browser worker(s) and 23 subagent(s), bound by memory pending: 100 task(s) browser 100 task(s) own tab + own terminal (parallel, one per host) → 4 terminal(s); hosts: site1.example, site2.example +98 more terminals needed: 4 limited by max_workers: max_workers is 4 (config or --max) the other 96 browser task(s) wait in the queue — each worker claims the next as it finishes
Lanes
A terminal exists to hold a browser tab. Work that never opens a page runs as a subagent inside the session you are already in — no window, no tab, no memory cost worth planning around.
Anything that acts on a live page: filling a form, posting, checking a listing. Pinned to one tab it created and never touches another worker's.
Research, drafting, summarising, code edits — everything with no page to click. Runs in parallel inside your current session.
Work that must not overlap: a shared file, an ordered migration, anything writing the same state.
Guarantees
fleet run 20 is trimmed to what fits unless you pass --force.rename(2);
eight agents racing for four tasks produce four winners and four clean misses.done requires the confirmation the
system actually returned; anything irreversible is screenshotted first.fleet probe-browser asks a real worker whether it can open
a tab and records the answer. A worker that finds none blocks its task instead of improvising..git/info/exclude, so your tracked files — including .gitignore — stay
exactly as they were.Start
# python3 stdlib only — nothing to pip install git clone https://github.com/MSKazemi/agent-fleet ~/agent-fleet ~/agent-fleet/bin/install ~/agent-fleet/bin/selftest # 67 checks, no browser needed cd ~/any/project fleet init fleet add "https://example.com/form/12" --title "vendor form" fleet add "summarise the three RFCs into a table" --kind research fleet plan # what will run, where, and why fleet run # exactly that many, and no more
Everything else is fleet help. The full command reference, the worker protocol and the
design notes live in the repository README.