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.
nexusbrain init, with a brain repo to sync.nexusbrain init --pglite is the local engine; --supabase or --url is Postgres. See Engines.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 lock | What a second command does |
|---|---|
nexusbrain serve | Stops right away and tells you the database is already open through serve. |
| Another command, such as a running embed | Waits up to 30 seconds for it to finish, then gives up with a timeout error. |
| A process that has exited | Removes the stale lock automatically and continues. |
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.
Your agents cannot reach the brain while serve is stopped, so pick a quiet moment.
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.
nexusbrain sync --dry-runYou should seeA summary of what would be added, modified and deleted. Nothing is written.
nexusbrain syncYou should seeA result such as First sync complete. or a summary line like +12 added, ~3 modified, -0 deleted, R0 renamed.
nexusbrain doctorYou should seeChecks marked [OK], or warnings telling you what to run next.
nexusbrain serveYou should seeThe server starts and your agents can reach the brain again.
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.
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.
nexusbrain sync --watch --interval 300You 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.
Press Ctrl+C.
You should seeThe command exits and releases the database.
5 consecutive sync failures. Stopping watch. and exits.nexusbrain serve. Run it on Postgres, or run one of them at a time.nexusbrain autopilot --install.nexusbrain serve running.You should seeAgents stay connected.
--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 2You should seeA result for each source, with a summary of how many succeeded, failed or were skipped.
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.
NEXUS_BRAIN_SYNC_TRACE=1 nexusbrain syncYou 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 variable | What it does |
|---|---|
--watch | Re-sync continuously on an interval. |
--interval N | Watch-mode interval in seconds. Default 60. |
--no-pull | Skip git pull before the sync. |
--dry-run | Show what would be synced without writing. |
--skip-failed | Acknowledge files that failed to parse so the sync can move past them. |
--retry-failed | Try previously failed files again, and clear them when they succeed. |
--no-embed | Skip embedding. Run nexusbrain embed --stale later. |
--break-lock | Clear a stuck per-source sync lock left by a dead process. Does not clear the local engine database lock. |
NEXUS_BRAIN_SYNC_TRACE=1 | Print the name of each file as it is imported, to find the file a sync hangs on. |
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.
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.