Guides / Brain

Running serve and sync together

Why the local engine allows one writer at a time, and how to run a large sync safely.

nexusbrain serve keeps the brain open so your AI agents can use it. nexusbrain sync reads your brain repo and writes new and changed pages into the database. Whether the two can run at the same time depends on your engine.

On the local engine (PGLite) only one process can have the database open, so a sync cannot start while serve is running. On Postgres they run side by side. This guide explains why, and gives safe workflows for both, including continuous syncing with watch mode.

Time
10 minutes
For
Anyone who runs `nexusbrain serve` for their agents and also syncs a brain repo

Before you start

  • A brain created with nexusbrain init, with a brain repo to sync.
  • Knowing which engine you use. nexusbrain init --pglite is the local engine; --supabase or --url is Postgres. See Engines.

01Why the local engine allows one writer

The local engine runs a full Postgres database inside the Nexus Brain process, compiled to WebAssembly. It supports exactly one connection. If two processes opened the same database folder at once, they could corrupt it in ways that only a wipe and restore can fix.

To prevent that, every brain command that opens the local database first creates a lock folder named .nexusbrain-lock inside the database folder, and removes it when it closes. nexusbrain serve holds that lock for as long as it runs.

Who holds the lockWhat a second command does
nexusbrain serveStops right away and tells you the database is already open through serve.
Another command, such as a running embedWaits up to 30 seconds for it to finish, then gives up with a timeout error.
A process that has exitedRemoves the stale lock automatically and continues.
Note

Postgres is a separate server that accepts many connections, so serve and sync can run together there. Sync still takes its own per-source lock, named nexusbrain-sync:<source_id>, so two syncs of the same source never overlap.

02Run a large sync on the local engine

Your agents cannot reach the brain while serve is stopped, so pick a quiet moment.

  1. Stop nexusbrain serve.

    Press Ctrl+C in the terminal running it, or quit the agent app that started it.

    You should seeNo nexusbrain serve process is left running.

  2. Preview the sync.

    nexusbrain sync --dry-run

    You should seeA summary of what would be added, modified and deleted. Nothing is written.

  3. Run the sync.

    nexusbrain sync

    You should seeA result such as First sync complete. or a summary line like +12 added, ~3 modified, -0 deleted, R0 renamed.

  4. Check the brain.

    nexusbrain doctor

    You should seeChecks marked [OK], or warnings telling you what to run next.

  5. Start serve again.

    nexusbrain serve

    You should seeThe server starts and your agents can reach the brain again.

Tip

If you do not want to stop serve, keep it running and use its MCP tools from your agent instead of running separate CLI commands.

03Keep a brain in sync with watch mode

Watch mode repeats the sync on a timer. It pulls from git and syncs, waits the interval, and does it again until you stop it.

  1. Start a watch with a five minute interval.

    nexusbrain sync --watch --interval 300

    You should seeWatching for changes every 300s... (Ctrl+C to stop). Each sync that finds changes prints a line such as [14:05:12] Synced: +2 ~1 -0 R0.

  2. Stop the watch when you are done.

    Press Ctrl+C.

    You should seeThe command exits and releases the database.

  • The default interval is 60 seconds.
  • After 5 failed syncs in a row, the watch prints 5 consecutive sync failures. Stopping watch. and exits.
  • The sync cost preview is skipped in watch mode. See Spend controls before watching a large repo.
  • On the local engine, a watch keeps the database open the whole time it runs, so it cannot run next to nexusbrain serve. Run it on Postgres, or run one of them at a time.
  • For a background service that keeps the brain up to date, see nexusbrain autopilot --install.

04Run serve and sync together on Postgres

  1. Leave nexusbrain serve running.

    You should seeAgents stay connected.

  2. Sync every registered source.

    --parallel N syncs up to N sources at once. Each source takes its own lock, so separate sources do not wait on each other. Use --parallel 1 to go one at a time.

    nexusbrain sync --all --parallel 2

    You should seeA result for each source, with a summary of how many succeeded, failed or were skipped.

Note

Each parallel source opens its own database connections. The help text estimates about parallel times workers times 2, plus the main pool, so keep --parallel modest on small Postgres plans.

05Sync flags for recovery and debugging

  1. Find the file a sync is stuck on.

    NEXUS_BRAIN_SYNC_TRACE=1 nexusbrain sync

    You should seeA line [sync] begin import: followed by a path for each file. The last path printed before the hang is the file to inspect.

Flag or variableWhat it does
--watchRe-sync continuously on an interval.
--interval NWatch-mode interval in seconds. Default 60.
--no-pullSkip git pull before the sync.
--dry-runShow what would be synced without writing.
--skip-failedAcknowledge files that failed to parse so the sync can move past them.
--retry-failedTry previously failed files again, and clear them when they succeed.
--no-embedSkip embedding. Run nexusbrain embed --stale later.
--break-lockClear a stuck per-source sync lock left by a dead process. Does not clear the local engine database lock.
NEXUS_BRAIN_SYNC_TRACE=1Print the name of each file as it is imported, to find the file a sync hangs on.

06Troubleshooting

A command says Nexus Brain's local database is already open through nexusbrain serve and cannot be opened at the same time.

Serve is holding the local database. Stop nexusbrain serve, then run your command again.

The brain will not remove the lock itself while that process is still running.

Nexus Brain: Timed out waiting for PGLite data-dir lock.

Another process held the database for more than 30 seconds. The message names its PID and command. Wait for it to finish, or stop it.

If that process is no longer running, remove the lock directory named in the message and try again. nexusbrain sync --break-lock does not clear this lock.

Another sync is in progress (lock nexusbrain-sync:default held by pid 1234 on my-host, started 2h ago).

Wait for that sync to finish.

If the process is dead, clear the lock with the command the message prints, for example nexusbrain sync --break-lock --source default.

Sync BLOCKED at abc12345: 2 file(s) failed to parse.

Details are in ~/.nexusbrain/sync-failures.jsonl, or run nexusbrain doctor.

Fix the files and run nexusbrain sync again, or run nexusbrain sync --skip-failed to move on without them.

A sync stops with no import progress for a number of seconds.

A stall watchdog stopped an import that made no progress. Run the sync again with NEXUS_BRAIN_SYNC_TRACE=1 to see which file it was working on.