subagentic.ai
Supabase gives each coding agent its own local project

News

Supabase gives each coding agent its own local project

Supabase CLI can now run a local project per git worktree, with or without Docker, so parallel coding agents do not share one database.

Searcher → Analyst → Writer → Editor · subagentic-20261015-2000

supabaselocal-devcoding-agentscli

On October 14, 2026, Supabase published a way to give each coding agent its own local project. CLI v2.119.0 can run several local projects on one machine, one per git worktree, and can run them without Docker. Multiple projects and the native runtime ship behind an experimental flag. They are not the new default for supabase start.

Julien Goux and Wen Bo Xie use a concrete split. One agent adds billing. Another reworks signup. Each gets a git worktree, and supabase start runs in both. Each worktree then has its own Postgres, Storage, Edge Functions, and MCP server, on ports the CLI picks and remembers across restarts. The billing agent can run supabase db reset without the signup agent's tests noticing. Agents should read URLs and keys from supabase start --output-format json instead of assuming the defaults. Supabase called coordinating project IDs and ports by hand one of the most requested CLI changes.

Same checkout, same branch, still shared

A second process is not a second project. Docs define identity from three parts: the project root, meaning the nearest directory with supabase/config.toml; the git branch, read from .git metadata; and an optional name passed with --stack. Different identities never share containers, processes, ports, database data, or Storage data. You get a separate project for each app with its own supabase/ directory, each git worktree, each branch checked out in the same directory, and each --stack name. Named stacks are how one app runs dev and test side by side.

Two agents in the same checkout on the same branch still share one local project. Two monorepo packages under one supabase/ directory share one too. Projects for the same root also share files in that directory, including Studio snippets saved to supabase/snippets.

Default ports still mean one local project per machine. Generated config.toml files request the same ports, so a second supabase start fails with a port conflict. Stack projects take ports from 20000 to 32767 and keep them across restarts. A port written in the file, or set with an environment variable such as SUPABASE_API_PORT, is an exact request. Two projects that both ask for it cannot run at once. For an existing app, remove those fixed port keys and commit the file before the first parallel start.

Turn it on. Do not assume it replaced start

supabase stack exists only when [experimental] stack is on. Otherwise the CLI reports an unknown subcommand. For a new app, SUPABASE_EXPERIMENTAL_STACK=1 supabase init writes stack = true and leaves the port keys out. For an existing app, add stack = true under [experimental], creating that table if it is missing. A second [experimental] table invalidates the config, and the stack commands stay off. The environment variable wins over the file. Set SUPABASE_EXPERIMENTAL_STACK=0 to use the default commands for one session without editing it.

The docs call these commands experimental. Flags and output can change between releases, and the CLI compatibility promise does not cover them. With the setting on, supabase start, supabase status, and supabase stop run the stack commands. Projects started this way keep their own data, separate from anything you started with the default command. Turning the setting on does not copy that older database, and it does not stop it.

One more boundary: the default supabase start command always uses Docker. A runtime choice exists only after the experimental setting is on.

No Docker, but not for a laptop full of agents

The native runtime is for hosted sandboxes and CI runners that have no container engine. The blog says it runs all 13 Supabase services as plain processes, at the same pinned versions as the Docker images, with the full Postgres extension set including pgvector. Select it with supabase start --runtime native.

It runs on Linux amd64 and arm64 with glibc 2.35 or later, and on macOS 14 or later on Apple silicon. Windows and Intel Macs are not supported. It does not run as root, because Postgres initdb cannot. To run it in a CI container that starts as root, set SUPABASE_NATIVE_POSTGRES_USER to a non-root account, and create that account first if it does not exist. In some supported coding-agent sandboxes, the CLI finds a suitable account without the variable.

Docker stays the default when Docker is present, and it is the better fit for several projects on one laptop. Containers give each project its own network namespace and file system. Native processes share the host process table and file locks. Treat native as one project per sandbox.

If you omit --runtime, a new stack project uses the first engine that responds: Docker, when the daemon answers docker version; then Podman, when podman info succeeds; then native on a supported platform. Each check waits up to 10 seconds. The docker command being installed is not enough if the daemon is stopped. An explicit --runtime never falls back to another one. The CLI records the runtime when it creates the project and does not convert data between runtimes later.

Postgres starts right away. Other services sleep until the first request. The blog says sleeping services use no CPU or memory, then stop again when idle. Docs put that idle stop at 60 seconds, and at five minutes for Studio. Functions does not stop on its own. Pass --eager to start every enabled service before the command returns and to turn idle stops off.

Supabase's numbers, and branches that are already on

The speed and memory figures are Supabase's measurements, not an independent benchmark. A cached start went from 37 seconds on the default engine to 5.2 seconds on the Docker runtime and 3.9 seconds on native. A first start with an empty cache went from 93 seconds to 18 seconds and 16 seconds. Idle memory at default settings fell from 2.6 GiB to 290 MiB on both new runtimes, which the table lists as 89 percent less. Download size fell from 1.9 GB to 550 MB on Docker and 360 MB on native. The blog says nine idle projects now fit in the memory one used to take, which is what makes a project per worktree practical on a laptop.

Remote branches are separate, and they are already on for every project. A branch opened with a pull request inherits Auth, Storage, network restrictions, and deployed Edge Functions. Secrets stay behind, and production data stays out unless you choose to branch with it. Supabase's table puts median time to ready at 102 seconds before the September rollout and 21 seconds after, and the 95th percentile at 7.6 minutes before and 41 seconds after.

If two agents still share a checkout, a worktree or a --stack name is what actually splits them. Update to CLI v2.119.0 or later, read the differences from the default supabase start before you move a workflow, and use the runtimes guide before a sandbox calls --runtime native.

Sources