Skip to main content

Work with agents in parallel locally

Saggar exists to take you further than a normal terminal. Keep many windows and tabs open, each with its own agent working on a discrete task, whether that's across several projects or a pile of tasks in the same one.

Agents on different projects rarely trouble each other. Agents sharing a repository can, and a few pitfalls are worth knowing before you start.

When you don't need to worry

Most of the time, small parallel work in one checkout is fine. If each task is discrete and you're committing straight to main, or bundling everything into one pull request, you'll usually get away with it.

It's safest when the tasks touch different parts of the codebase. One agent refactoring some tests while another builds an unrelated piece of UI will rarely step on each other.

How agents collide

Agents have become much better at noticing each other, but collisions still happen in two main ways.

Git operations

This is the most common one. Depending on your instructions, agents often commit their work, create branches to contain it, and open pull requests. With several agents doing that in one checkout:

  • they open competing branches, or switch the branch out from under each other;
  • one agent commits another's half-finished changes along with its own;
  • pull requests end up containing several unrelated changes;
  • work goes missing after a stash, reset, or checkout; and
  • an agent stalls, because it can see changes it didn't make and won't proceed until someone explains them.

Overlapping edits

When two agents change the same code, one can undo the other's edits, or both can make changes that break each other in ways that are hard for them to sort out and hard for you to understand afterward. Keep coupled work in one session, or sequence it: let one agent finish the shared piece, then start the rest.

Isolate bigger work in worktrees

For substantial parallel work, or any agent that will branch and commit, give it a Git worktree. A worktree is a second checkout of the same repository in its own folder, on its own branch. The work is isolated, yet still connected to the root project: it shares history, and its branch is visible from your main checkout, ready to merge or review.

There are three ways to get an agent into one:

  • In Saggar. Choose In a new worktree… from the new-session menu. Saggar creates the branch and checkout, then opens the session there. See Project workspace for details.
  • In the task. Tell the agent to do the work in a new worktree, for example "Fix issue #123 in a new worktree and open a pull request."
  • In your agent instructions. Add guidance to AGENTS.md or CLAUDE.md so every agent knows when to move into one without being told.

A starting point for your instructions file:

## Parallel agents

Other agents may be working in this checkout. Treat changes you didn't make as
someone else's work.

- Never switch branches, stash, reset, or discard changes you didn't make.
- Stage only the files you changed.
- For a larger change, or any change that needs its own branch or pull
request, create a worktree from HEAD and work there.

Keep the main checkout for the task you expect to supervise closely, and put bounded, reviewable work in worktrees.

A worktree prevents file-level collisions, not logical ones. Two branches can still make incompatible decisions, so tell each agent what it owns and what it must not change.

Watch your machine

Isolation moves the collisions from Git onto your hardware.

Disk

Every worktree is a full checkout with its own dependencies and build output. A 500 MB repository whose build artifacts run to several gigabytes, times ten agents, will fill a drive quickly.

Shared caches cut the cost, since a worktree can reuse work the others have already done instead of downloading and compiling everything again:

  • JavaScript. pnpm hard-links packages from one store on disk, so extra checkouts cost little in node_modules.
  • Rust and C. sccache shares compiled output across checkouts.
  • Swift. This is the weak spot, as SwiftPM has no shared cache. The best option is to seed a new worktree's .build folder with an APFS copy-on-write clone of the main checkout's, using cp -c. SwiftPM records absolute paths in its build output, so test whether it reuses the clone or rebuilds from scratch before relying on it.

Be deliberate about how many you open, and prune them once their work has merged. Review cleanup… in Saggar measures every extra worktree and lists the ones safe to remove, largest first. Outside Saggar, git worktree remove deletes a checkout and git worktree prune tidies up after folders you've already deleted.

Memory and CPU

Builds and test suites are heavy. Several agents running them at once can exhaust memory, freeze your machine, and make the tasks themselves time out and fail. The agents then chase failures that have nothing to do with their change.

A few ways to keep that in check:

  • Serialize the heavy work with a lock. Wrap builds and full test runs so only one runs at a time, and point agents at the wrapper. On macOS, lockf -k /tmp/build.lock npm run build waits for any other holder before it starts. Agent tools time out long shell commands, so a queued build can be killed before it runs. Agents keep fighting over my CPU walks through that problem and a fix: an MCP server that queues the builds, released as Agent Task Queue.
  • Ask for targeted checks. A single test file is cheaper than the full suite, and agents can leave the full run for the end.
  • Cap parallelism inside tools. Most test runners and bundlers accept a worker limit, which matters more when several are running at once.

Other shared resources

Anything outside the checkout is still shared. Two dev servers will fight over the same port, which the ports panel (⌘⇧P) helps untangle. Agents running migrations against the same local database, or writing to the same global cache or config, can still collide even in separate worktrees.

Why not use cloud agents?

Cloud agents avoid most of this. Each runs in its own container, so there's no risk of colliding changes, nothing touches your machine's disk or memory, and they clean up after themselves.

The trade-offs push a lot of work back to local sessions:

  • Visibility. You see what a local agent is doing as it does it, not a summary afterward.
  • Steering. You can interrupt a local agent mid-task and redirect it.
  • Orchestration. Local sessions sit side by side with your terminals, monitors, and editor, and Saggar tells you which one needs you.
  • Context. A local agent has your environment: installed tools, local services, credentials, MCP servers, and uncommitted work.
  • Running the code. You can run, click through, and test the result on your machine before it goes anywhere.
  • Merging. A local branch is one command from main, with no round trip through a hosted pull request.
  • Portability. Local sessions work with any agent CLI, rather than tying your workflow to one vendor's platform.

Many people use both: cloud agents for well-bounded, fire-and-forget tasks, and local sessions for anything you'll want to watch, steer, or run.