Chapter V · Knowledge management

Obsidian Sync Without Conflict Roulette

Tested on
rclone 1.73.5 bisync against a Google Drive remote, systemd 255 user timer, OpenClaw 2026.10.4, Brigade 0.28.0, Ubuntu 24.04
Last updated
2026-10-17

One vault, one sync layer, one place for automation to write. That is how you get bidirectional cloud sync without waking up to three “conflicted copy” files and a broken notes index.

What this is

Obsidian sync gets messy fast when desktop, phone, and automation all act like they own the vault. You end up with duplicate notes, attachments that exist on one device only, and indexes that drift because two writers touched the same file seconds apart.

This guide is the pattern that has held up best for me: one canonical vault, one sync mechanism, inbox-first capture on mobile, and strict rules about which files automation is allowed to touch. The vault itself follows a PARA-style Zettelkasten note system: projects, areas, resources, and archive as the folder spine, with small atomic notes instead of giant omnibus files. It is cloud-backed and bidirectional, but it is not a free-for-all.

Why this way

There are three common approaches:

ApproachFeels easyActually breaks because
Two independent vault copiesNo setup beyond pointing each device at a folderThey drift immediately. Plugins, attachment paths, and note IDs stop matching.
Multiple sync tools stacked together”Extra safety”It is not safety. It is conflict multiplication. One tool uploads while the other rewrites metadata.
One canonical vault + one sync layer + writer rulesSlightly stricter up frontThis is the one that stays boring, which is the whole point.

The hard truth: sync failures are usually not a cloud-provider problem. They are a writer-discipline problem. If phone capture, desktop editing, and automation all touch the same long-lived files, conflict copies are inevitable.

Prerequisites

Before / After

Before: notes arrive from mobile, desktop, and scripts into random folders. Some filenames collide. Daily notes get edited by more than one device at once. Attachments lag behind note text. Search results show duplicate files with slightly different timestamps.

After:

Implementation

1. Pick one canonical vault root

Every device should mount or open the same vault layout.

Example structure:

Obsidian/
└── Vault/
    ├── 00 - Inbox/
    ├── 01 - Projects/
    ├── 02 - Areas/
    ├── 03 - Resources/
    ├── 04 - Archive/
    └── Attachments/

That layout is intentionally PARA-shaped. The note style inside it is Zettelkasten-flavored: short atomic notes, strong links, and as little monolithic “master note” sprawl as possible.

Do not keep a “desktop vault” and a separate “mobile vault” and try to merge them later. That is how you get duplicate note universes.

2. Use exactly one sync layer

Choose one of these patterns:

PatternGood fitRule
Obsidian SyncYou want the least operational dramaLet Obsidian own the sync path. Do not also mirror the vault with a cloud-drive client.
Cloud drive mirrorDesktop-first setup with a local synced folderThe vault lives inside the mirrored folder. Every device uses that same mirror path.
Provider-backed sync pluginYou need a backend Obsidian can talk to directlyLet the plugin be the sync layer. Do not stack a second sync client on top.

The rule is blunt because it needs to be: one vault, one sync engine.

3. Separate capture from curation

Mobile should be optimized for fast capture, not perfect filing.

This keeps sync boring because only one surface is doing heavy reorganization.

4. Give summary files a single owner

Master indexes, dashboards, and generated overview files are conflict magnets. They change often, they stay open for a long time, and they tempt every automation script to rewrite them.

Pick one owner for each class of file:

If a file is likely to stay open in Obsidian for hours, do not let a background script rewrite it.

5. Keep automation atomic

Automation should prefer creating or updating small, topic-scoped notes instead of rewriting giant “everything” files.

Good:

00 - Inbox/2026-05-06-router-maintenance.md
03 - Resources/networking/bgp-community-notes.md

Bad:

03 - Resources/master-notes.md
Home.md
Today.md

Atomic notes sync cleanly. Monolithic notes invite merge hell.

6. Normalize filenames and attachment paths

Set and enforce a few boring rules:

Most sync conflicts start as naming slop long before they become visible as conflict copies.

7. Add a reconciliation pass

Once a day or once a week, do a quick audit:

This is five minutes well spent. Letting small vault drift sit for a month is how you end up losing a Saturday to note archaeology.

8. Wire the sync as one timer with a bounded blast radius

My version of “one sync engine” is rclone bisync between a Drive folder and a local vault, run by a systemd user timer every two minutes. The service is a oneshot with three jobs around the sync itself:

# ~/.config/systemd/user/obsidian-sync.service
[Service]
Type=oneshot
# Deliver agent notes into the vault inbox first. The leading "-" means a bridge
# failure never blocks the vault sync.
ExecStartPre=-%h/.openclaw/workspace/scripts/notes-to-vault.sh
# File the just-delivered notes into their work-log folders.
ExecStartPre=-%h/.openclaw/workspace/scripts/agent-notes-filer.sh
ExecStart=%h/bin/rclone bisync gdrive:Obsidian %h/Obsidian --resilient --recover --create-empty-src-dirs --max-lock 2m
# Refresh the local notes index after the sync, again non-fatal.
ExecStartPost=-%h/bin/vault-index
# ~/.config/systemd/user/obsidian-sync.timer
[Timer]
OnBootSec=30
OnUnitActiveSec=2min
AccuracySec=10s

(gdrive:Obsidian and vault-index are placeholders for your remote path and whatever indexes your notes. The rest is what I run.)

A second drop-in raises TimeoutStartSec to 30 minutes and runs a one-way projection of canonical agent memory into a subfolder of the vault before the sync. The projection is brigade memory project-vault --target <workspace> --vault <vault>, and it is the only thing allowed to write that subfolder. That is the “single owner” rule from step 4 applied to a generated tree. A failed projection is logged and retried. It does not block your notes from syncing.

The notes bridge is conflict-safe by design. It records each delivered note’s hash in a ledger and skips unchanged ones. It skips a note whose basename already exists elsewhere in the vault, because that means you already filed it. If the destination exists, differs from the source, and was edited in the vault more recently, it writes a .conflict-<timestamp> sibling instead of overwriting your edit.

--max-lock 2m deserves its own paragraph, because leaving it out breaks --resilient and --recover in a way you will not see until the first interrupted run. Without --max-lock, rclone writes a bisync lock with an effectively infinite expiry. Kill the process mid-sync (a reboot, an OOM kill, a stop) and the lock stays. Every later run then fails with “prior lock file found” and the recovery flags never get a chance to act. That wedged my vault for 15 days in July 2026 before I noticed. With --max-lock 2m, a live run keeps renewing its lock, so only a lock whose owner is gone expires. The minimum rclone accepts is 2 minutes. Set it to at least that, and keep your timer interval from overlapping a run that legitimately takes longer.

The first bisync of a new pair of paths needs a one-time --resync per rclone’s bisync docs. After that, --resilient --recover handle ordinary interruptions without it.

Verification

On a desktop with a local mirror of the vault:

# 1. Find obvious conflict artifacts
find ~/Obsidian/Vault -type f \( -iname '*conflict*' -o -iname '*conflicted copy*' \)

# 2. Find duplicate basenames in different folders
find ~/Obsidian/Vault -type f -name '*.md' -printf '%f\n' | sort | uniq -d

# 3. Spot notes with missing attachments (basic check)
grep -Rho '!\[\[.*\]\]' ~/Obsidian/Vault | sed 's/^!\[\[//; s/\]\]$//' | while read -r f; do
  find ~/Obsidian/Vault -type f -name "$f" | grep -q . || echo "Missing attachment: $f"
done

And check the sync service itself:

# Timer is firing
systemctl --user list-timers obsidian-sync.timer
# Expected: a NEXT time within two minutes

# Last run succeeded
systemctl --user show obsidian-sync.service -p Result,ExecMainStatus
# Expected: Result=success, ExecMainStatus=0

# Bisync flags include the lock fix
systemctl --user cat obsidian-sync.service | grep -- '--max-lock'
# Expected: a line ending in --max-lock 2m

# A stuck lock shows up in recent logs
journalctl --user -u obsidian-sync.service -n 50 --no-pager | grep -i 'lock file'
# Expected: no "prior lock file found" lines

Manual test loop:

  1. Create a note on desktop in 00 - Inbox/
  2. Confirm it appears on mobile
  3. Edit one line on mobile
  4. Confirm the same file updates on desktop without a duplicate file appearing
  5. Move the note on desktop to its long-term folder
  6. Confirm mobile sees the move, not a second copy

If that six-step loop is clean, your sync model is probably healthy.

Gotchas

A missing --max-lock turns one crash into a long outage. See step 8. The symptom is a service that fails on every tick with a prior-lock message while nothing about your vault looks wrong. Check the flag before you suspect the remote.

A bridge that blocks the sync is worse than a bridge that fails. The leading - on each ExecStartPre and ExecStartPost line is deliberate. My notes bridge, the filer, and the post-sync index all failed at some point, and the vault kept syncing because none of them were allowed to fail the unit.

Stacking sync tools is the fastest path to pain. Running Obsidian Sync plus a cloud-drive mirror plus a provider plugin sounds redundant and safe. It is neither. Each layer notices file changes at slightly different times and happily manufactures conflicts for you.

Mobile background sync lies by omission. Many phones delay app network activity when the app is not foregrounded. You think the note synced because the spinner stopped. It did not. Open the vault and verify recent notes actually landed before assuming capture is safe.

Generated index files are conflict magnets. If an automation job rewrites a dashboard note while you are staring at it on another device, the sync tool has no magical way to know which copy you “meant.” Give summary files one owner and keep the other devices read-mostly.

Attachments drift more quietly than notes. Text sync failures are obvious. Attachment failures are sneaky. The note is there, the image link looks fine, and the actual file never arrived on the phone. Check attachment paths during reconciliation.

Filename normalization matters more than people think. Two notes that differ only by punctuation, whitespace, or letter case will eventually hurt you on a mixed device fleet. Decide the naming scheme once and keep it boring.