Skip to content

Parallel & remote agents

The last chapter was about a single agent working a single thread. This one is about more than one at once — and the three different shapes that takes in Cursor, because they are not the same primitive wearing three hats. The move that anchors the chapter is the loudest of them: Cursor 2.0’s multi-agent sidebar, where one prompt fans out to a fleet of parallel agents, each in its own isolated copy of your repo, and you pick the winner.

Hold onto the core idea, because it carries the whole chapter. When a task has more than one reasonable approach — or more than one independent slice — running it once gives you one answer and no way to know if it was the best one. Running it several ways at once, in isolation, gives you a slate to compare. The cost is more compute and a review step at the end; the payoff is that you stop betting the whole task on a single agent’s first instinct. That trade is the spine of this chapter, and everything below is learning the three machines Cursor gives you to make it — and which machine fits which job.

You’ve inherited budgetcli — a small self-hosted budgeting API plus a thin web client — and you don’t fully trust it yet. Two things now need doing, and neither is a clean fit for a single agent grinding through one thread:

Pick the right caching layer for the reports endpoint — there are three defensible approaches and you can’t tell which wins from reading alone. And separately, migrate every money field across the codebase from floats to integer cents without the workers reading each other’s half-written files.

The first is a decision under uncertainty: in-process LRU, Redis, or a materialised view — each has a different shape, and the honest answer is you won’t know which is cleanest until you see all three implemented against your actual code. The second is genuinely parallel but write-heavy: the same mechanical change applied across many files at once, where the danger isn’t the change itself but several agents editing one working tree and tripping over each other mid-edit.

Both jobs want parallelism — but for different reasons, and that difference is the whole chapter. The first wants competing agents you compare. The second wants cooperating agents you keep walled apart. Cursor’s multi-agent sidebar does both, and it does them with the same isolation mechanism, so we start there.

Flavour one — local fan-out from the multi-agent sidebar

Section titled “Flavour one — local fan-out from the multi-agent sidebar”

The Cursor 2.0 multi-agent sidebar takes a single prompt and runs it across several agents at once, in parallel, each in its own isolated copy of the codebase. The cap is small and deliberate — up to eight agents on a single prompt.

Two distinct ways to use it, matching the two jobs:

Competing agents — same prompt, compare the results. Point the same prompt at several agents and let each take its own swing. This is the caching decision: you write the brief once, fan it out, and get back several complete implementations to compare side by side instead of one you have to trust blind.

> Add a caching layer to the reports endpoint in api/reports.py.
Keep the public response identical; add cache invalidation on any
write that touches a report's underlying rows. Make it production-shaped,
not a sketch.

Dispatched across three agents, you get three real branches to read — one that reached for in-process LRU, one for Redis, one for a materialised view — each having actually written the code, run against your real types, and produced a diff you can review. You’re no longer guessing which approach is cleanest; you’re reading three answers and keeping the best.

Cooperating agents — different slices, no shared working tree. Point each agent at a different slice of the same job. This is the float-to-cents migration: agent one takes the parsing layer, agent two the storage layer, agent three the report formatting, all running at once. They’re not competing — they’re dividing labour — and the reason they don’t corrupt each other is the isolation mechanism underneath.

When several agents edit one working directory at once, the failure isn’t merge conflicts — it’s worse, and it’s the reason isolation is load-bearing rather than a nicety. Picture two agents in one directory. Agent A is halfway through rewriting money.py, the file saved in an inconsistent state mid-edit. Agent B, working a path that imports it, reads that file right now and reasons over a half-written version that never existed in any commit and never will. The result is a non-deterministic failure even though the two slices were logically independent. Agents make this worse than humans do — they don’t pause to notice something looks off, they auto-iterate on the bad state, and they can’t attribute a passing test to the right branch.

A git worktree fixes exactly this. One repository, but multiple checked-out working directories — each with its own branch, its own index, its own files on disk — all sharing the same underlying object database and history. That buys file-level isolation (B can’t see A’s unsaved edits), index isolation (each has its own staging area), and a branch lock (git refuses to check out a branch that’s already checked out elsewhere). Cursor’s multi-agent sidebar does this for you: per the 2.0 changelog, it “uses git worktrees or remote machines to prevent file conflicts,” so each agent operates in its own isolated copy of the codebase. The cooperating agents on the cents migration never read each other’s half-written files, and the competing agents on the caching decision never clobber each other’s branch.

The isolation a worktree gives you is code state — files, index, branch pointer. It does nothing for execution state, and that gap bites the cents migration the moment a worker tries to run the test server. Three agents in three worktrees still share ports, the dev database, and a root .env — so two of them binding localhost:8000 or running concurrent migrations against one shared dev database will collide outside any worktree’s protection. The rule of thumb: anything that lives outside the working directory is not isolated, and you handle it yourself (a per-worker port range, a per-worktree database file). And one line worth its own sentence — runtime isolation is not security isolation. A worktree keeps honest, cooperating agents from tripping over each other; it does nothing against untrusted code or prompt injection. For that, the guardrails are the sandbox and permission defaults from the permissions chapter, layered underneath.

Reviewing and merging the competing results

Section titled “Reviewing and merging the competing results”

Fan-out’s real work happens at the end, not the start — and skipping it is how you turn a slate of options into a faster way to ship the wrong one. Each agent comes back with a branch and a diff. For the competing caching agents, you read all three against one question you decided up front — which keeps the response identical with the least new surface area? — and you keep one. The Redis branch might be cleanest in isolation but drag in an infrastructure dependency you don’t want; the materialised-view branch might be the least code but the hardest to invalidate correctly. You’re making an engineering call across three real implementations, which is exactly the call you couldn’t make from reading the endpoint alone. The other two branches get thrown away — that’s not waste, that’s the point. You paid compute to buy a comparison.

For the cooperating cents agents, the merge is a different shape: you’re not picking a winner, you’re integrating three slices that should compose. Review each branch on its own terms — does the parsing slice actually convert at every entry point, does the storage slice round-trip cleanly — then merge them in sequence, running the test suite after each so a silent failure in one slice can’t hide behind a green run from another. The discipline that carried every earlier chapter applies here, just multiplied: what comes back is a proposal you review, never a result you apply. More agents means more surface for a confident-but-wrong diff, so the review gate gets more important as you widen the fan-out, not less.

So the shape that works for flavour one: fan out when the task has competing approaches you want compared or independent slices you want done at once; let the worktree isolation keep the agents from corrupting each other; namespace anything that lives outside the working tree yourself; and treat the returning branches as a slate to review, never a result to merge blind.

The sidebar fan-out is a blunt, one-shot instrument: you point a fleet at a prompt and compare what comes back. Subagents are the opposite — a scalpel. Introduced in Cursor 2.4, a subagent is a worker you define ahead of time, with its own context window, that the main agent delegates a scoped job to and gets back only the conclusion. The hundreds of file reads it did to reach that conclusion never enter your main thread.

A subagent is a markdown file with YAML frontmatter, discovered from project and user paths:

  • Project: .cursor/agents/, .claude/agents/, or .codex/agents/
  • User: ~/.cursor/agents/, ~/.claude/agents/, or ~/.codex/agents/

Project-level files take precedence on a name collision, and within a level .cursor/ wins over the .claude/ and .codex/ fallback paths. (Those fallbacks exist so a repo already carrying Claude Code or Codex agent files gets picked up without a rewrite.)

The frontmatter is a small, scoped set:

---
name: verifier
description: Read-only checker — confirms a change does what it claims, runs tests, reports pass/fail with evidence
model: inherit
readonly: true
is_background: false
---
You are a verification agent. Read the change under review, run the
relevant tests, and report PASS or FAIL with the exact evidence. Do
not edit files. Do not fix what you find — only report it.

The fields, each earning its place:

  • name — the handle you invoke it by; defaults to the filename if omitted.
  • description — the agent reads this to decide when to delegate to this subagent automatically. Write it as a trigger, not a title.
  • model — which model the subagent runs; defaults to inheriting the parent’s. A read-only scanner doesn’t need your most expensive model, so this is a cost lever.
  • readonly — when true, the subagent can read and reason but not write. This is the lock that makes a verifier or an explorer safe to let run unattended.
  • is_background — whether the subagent runs in the background rather than blocking the main thread; defaults to false.

Invocation is threefold:

  • Automatic delegation — the main agent reads each subagent’s description and routes a matching task to it without you asking. This is why the description is a trigger sentence, not a label.
  • Explicit /name/verifier check the new caching branch routes the rest of the line straight to that subagent.
  • Natural-language mention — “have the verifier confirm the auth flow” does the same thing in prose.

The isolation is the same idea as the worktree fan-out, but applied to context rather than files: the subagent works in its own context window, so the noise it generates — the greps, the file dumps, the test logs — lands in its memory and never crowds your main thread. Where the sidebar fan-out isolates the filesystem so cooperating agents don’t corrupt each other, a subagent isolates the conversation so a noisy job doesn’t bury your decisions. On budgetcli, that’s the difference between “scan every endpoint for the float-handling bug” filling your main thread with a hundred file reads, versus a read-only subagent doing the scan in its own window and handing back only the list of offenders.

The third flavour leaves your machine entirely. Cloud Agents (formerly Background Agents) are full agents that run in isolated cloud VMs rather than locally — they clone your repo to a fresh branch, work, push results back, and you review the branch like any other.

The environment they run in is reproducible from a checked-in file, .cursor/environment.json, configured one of three ways:

  • Agent-led setup — the agent installs what it needs interactively, and you snapshot the result.
  • A saved snapshot — a captured machine image the agent boots from.
  • A Dockerfile — a fully declared, reproducible build environment.

The snapshot path looks like this — illustrative, not the full schema:

{
"snapshot": "POPULATED_FROM_SETTINGS",
"install": "npm install",
"start": "npm run dev",
"terminals": [
{ "name": "tests", "command": "npm test -- --watch" }
]
}

The snapshot, install, start, and terminals fields are the real field names (terminal entries take a name and command, with optional ports). One thing the example deliberately leaves out: the Dockerfile mode doesn’t use a bare snapshot field — it uses a build object ({dockerfile, context}) instead. The canonical schema is published at cursor.com/schemas/environment.schema.json; consult it before treating any one example as the whole story.

Because a Cloud Agent doesn’t live in your editor, it’s reachable from wherever your work already happens:

  • Cursor Desktop — pick Cloud from the agent input.
  • Cursor web (cursor.com/agents) — drive it from any device, including your phone.
  • Slack@Cursor in a channel.
  • GitHub — comment @cursoragent on a PR or issue (note: it’s @cursoragent here, not @cursor — the handle differs from the other hosts).
  • Linear@cursor on an issue.
  • REST API — spawn and manage agents programmatically, for webhooks and CI.

For budgetcli, a Cloud Agent is the right tool when the work shouldn’t tie up your local machine and doesn’t need your eyes mid-flight: “open a PR upgrading the test dependencies and confirm the suite still passes” is a job you fire from Slack on the way out and review as a PR when it’s green — your laptop never enters the loop, and the cloud VM is sandbox-by-construction so the local-machine threat model doesn’t apply.

Put them side by side, because the whole point of the chapter is knowing which one a given job wants. They are not interchangeable — they trade along different axes:

Local fan-out (sidebar)SubagentsCloud Agents
Where it runsYour machine, parallel worktreesYour machine, isolated contextRemote cloud VM
How you reach itMulti-agent sidebar, one promptAuto-delegate, /name, or NL mentionDesktop / web / Slack / GitHub / Linear / REST API
ShapeOne-shot, broadcast-and-compareDelegated, defined ahead of timeDetached, fire-and-review
IsolatesThe filesystem (worktrees)The context windowThe whole machine
Best forCompeting approaches or parallel slices you’ll review togetherA scoped, noisy, or repeatable job you don’t want in your main threadWork that shouldn’t tie up your laptop and doesn’t need your eyes mid-flight

Read it as one question asked three ways — where should this work happen, and how isolated does it need to be? The local fan-out isolates files so a fleet of agents can edit at once without corrupting each other. A subagent isolates context so a noisy job doesn’t bury your main thread. A Cloud Agent isolates the whole machine so the work leaves your laptop entirely. Same instinct — push work somewhere isolated and review what comes back — at three different radii.

By the end of this chapter the question to ask before any heavy or parallel task is which radius it wants: fan it out locally to compare, delegate it to a subagent to keep your thread clean, or send it to the cloud to get it off your machine. Pick the wrong radius and you’ll feel it — a Cloud Agent for a thirty-second scan is overkill, a sidebar fan-out for a job with one obvious approach is just spending compute to feel busy.