Claude Code Projects Now Fans Out Parallel Agents: Governing the Budget They Burn

·11 min read·Evergreen Tools Team

On September 17, 2026, Anthropic rebuilt Claude Code's Projects feature. Instead of slicing work yourself, you describe a goal and a coordinator breaks it into parallel threads, each running as its own Claude Code cloud session with its own branch and its own copy of the repository. A thread can run tests, migrate callers, and open pull requests, and threads build a shared memory over time. The beta opened to select Pro and Max subscribers using cloud sessions, with Team and Enterprise access later and local execution on the roadmap. It is a step from humans orchestrating many sessions toward the agent orchestrating itself. But the same coverage carried the line worth remembering: this can drain your plan before lunch. Parallelism is not free. It just moves the bill earlier.

1. What Actually Shipped

Per The Decoder, DevOps.com, and The New Stack: Projects now runs from a single conversation, where a coordinator splits a development goal into multiple threads. For repository-based work, each thread is a separate cloud session with its own branch and copy of the repo, so multiple parts of a task move forward without one session overwriting another's changes. You can follow the whole run from the main project conversation or open an individual thread to watch and redirect it. Threads can migrate callers, run tests, and open pull requests, and the coordinator decides which chain should be merged first. Shared memory lets threads build a common context over time, and a library collects uploaded files and results.

// Fan out a goal, but cap concurrency and give every thread a budget.
type Thread = { id: string; branch: string; budgetUsd: number; spent: number };

const MAX_THREADS = 3;            // matches your plan's headroom, not your ambition
const PER_THREAD_BUDGET = 0.80;   // USD - a thread that exceeds this is stopped

async function fanOut(goal: string, subtasks: string[]): Promise<Thread[]> {
  const queue = [...subtasks];
  const running: Thread[] = [];
  const done: Thread[] = [];

  while (queue.length || running.length) {
    while (running.length < MAX_THREADS && queue.length) {
      const task = queue.shift()!;
      const thread = await startCloudSession({
        task,
        branch: branchFor(task),
        budgetUsd: PER_THREAD_BUDGET,
      });
      running.push(thread);
    }
    const finished = await Promise.race(running.map((t) => waitFor(t)));
    running.splice(running.indexOf(finished), 1);
    done.push(finished);
  }
  return done;
}
Parallel coding agents at work

One goal, many threads, many branches

2. Why Fan-Out Rewrites Your Cost Model

With a single session, cost is roughly one person for one stretch of time. With fan-out, cost becomes concurrency times duration, and each thread is a full session drawing on the same plan. The New Stack captured it bluntly: the feature could drain your plan before lunch. The reason is not subtle. Open five threads and the coordinator spends at the rate of however many threads you opened. The instinct is to open more for speed, but what scales is not velocity; it is spend. The subtler part is duration: threads keep working after you close your laptop, which is a feature in the product and a running meter on the invoice.

// Each thread is a full session: meter tokens and dollars per thread,
// never per project, or you will not see which thread ran away.
function meter(
  threadId: string,
  usage: { input: number; output: number },
  prices: { in: number; out: number },
) {
  const cost = (usage.input / 1e6) * prices.in + (usage.output / 1e6) * prices.out;
  db.threads.update(threadId, { $inc: { tokens: usage.input + usage.output, spent: cost } });
  const row = db.threads.get(threadId);
  if (row.spent > row.budgetUsd) return stopThread(threadId, "budget");
  return "ok";
}

3. Parallel Work Always Bills You at the Merge

Fan-out is only the first half. Fan-in is where the cost lands. Five branches that each succeed and each open a pull request sounds excellent until their edits overlap and you inherit a merge war. Every conflict costs human attention, and human attention is usually dearer than tokens. Worse, ordering matters: which branch merges first determines whether the others must be re-run. Knowing which chain should merge first is exactly what the coordinator brings, but the ordering call is still a human one. The honest question to ask before you start: can this goal actually be split into subtasks that do not touch each other? If it cannot, parallelizing just makes five copies of the same problem.

# Before the coordinator merges anything, find the threads that will collide.
# A fan-out of five branches with overlapping edits is a merge war, not speed.
for b in $(git branch --list 'agent/*' --format='%(refname:short)'); do
  git merge-tree --write-tree main "$b" >/dev/null 2>&1 || echo "CONFLICT likely: $b"
done

# Merge the smallest, least entangled branch first, then re-run the check.
# Let the coordinator merge; you decide the order. That is a human call.
Merging branches from multiple agents

Parallelism always bills you at the merge

4. Pricing the Fan-Out: Concurrency Caps and Budget Guards

Treat parallelism as a cost-control problem and the shape becomes obvious. First, set a concurrency cap, sized to your plan's headroom rather than your ambition; three is safer than seven. Second, give every thread a budget and stop it when it is reached, rather than letting it run indefinitely. Third, set a whole-run ceiling, because the coordinator has no idea what your invoice looks like and the guard has to live outside it. Fourth, run a merge pre-flight with git before you start and merge the least entangled branch first. Fifth, log every run's thread count, tokens, spend, and merge cleanliness, then look at the one number that matters: dollars per merged pull request.

// A run-level ceiling beats per-thread limits. The coordinator does not know
// what your invoice looks like, so the guard has to live outside it.
const RUN_CEILING = 6.00;

async function guard(runId: string) {
  const run = db.runs.get(runId);
  if (run.spent >= RUN_CEILING) {
    await stopCoordinator(runId);
    await stopAllThreads(runId);
    notify({ runId, reason: "run ceiling reached", spent: run.spent });
  }
}
setInterval(() => guard(runId), 30_000);

5. In Practice: From Concurrency Gate to Budget Sentinel

The first snippet is a fan-out with a concurrency cap: at most three threads at once, each carrying a budget, each yielding the slot when it finishes. The second meters cost per thread, because if you meter per project you will never see which thread ran away. The third is a merge pre-flight that uses git merge-tree to surface branches that will probably conflict, and to suggest an order by entanglement. The fourth is a run-level budget sentinel: every thirty seconds it checks the ceiling and stops both the coordinator and every thread at once. The fifth logs the run, so you can chart cost per merged pull request.

// Log every run: threads, tokens, dollars, and whether the merge was clean.
type RunLog = {
  runId: string;
  threads: { id: string; branch: string; tokens: number; usd: number; pr?: string }[];
  mergedClean: boolean;
  wallClockMinutes: number;
};

export function logRun(run: RunLog) {
  db.runs.insert({ ...run, ts: new Date().toISOString() });
}
// Then chart cost per merged pull request. One number tells you whether
// parallelism is paying for itself or merely spending faster.
Cost per merged pull request

The only number that matters: dollars per merged PR

6. A Checklist: Five Questions Before You Fan Out

First, can this goal really be split into subtasks that do not touch each other? Second, how much headroom does my plan actually have for concurrency? Third, what is each thread's budget, and who stops it when it is crossed? Fourth, is there a hard ceiling covering the whole run? Fifth, can I compute cost per merged pull request? The one most often skipped is the first. Plenty of goals look splittable and are quietly coupled, and forcing them apart simply manufactures conflicts and rework. The right posture is not how many threads can I open, but how many threads can I open and still trust the code that comes out the other side. Speed you can buy. Maintainability you cannot.

📌 Frequently Asked Questions

When did this Claude Code Projects change ship?

Per The Decoder and DevOps.com, Anthropic announced the Projects redesign on September 17, 2026, opening a beta to select Pro and Max subscribers using cloud sessions, with expansion to more Pro/Max users, then Team and Enterprise, and local execution later.

Does each thread share one session or run its own?

According to DevOps.com and The New Stack, for repository-based work each thread runs as a separate Claude Code cloud session with its own branch and copy of the repository, so multiple parts can proceed without overwriting each other's changes.

Why can this feature drain a plan before lunch?

Because every thread is a full session drawing on the same plan. The New Stack notes the coordinator spends at the rate of however many threads you opened, so more concurrency means faster spend, and threads keep running after you close your laptop.

What are the cost risks of parallel threads?

Three main ones: concurrency multiplies spend directly; background threads keep the meter running; and merge conflicts at the fan-in stage consume human attention that is dearer than tokens, with ordering affecting whether work must be re-run.

How should a team govern this parallelism?

Set a concurrency cap, give every thread a budget, add a whole-run ceiling guarded from outside the coordinator, run a git merge pre-flight and order merges by entanglement, and log each run's threads, tokens, spend, and merge cleanliness to track cost per merged PR over time.