Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

SimpleSync

Jiří Čepelka Jiří Čepelka 225 downloads

Sync your vaults through your own self-hosted SimpleSync server. Enter the server address, name and password, then pick a vault.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates15

Simple self-hosted sync for Obsidian: a small server plus an Obsidian plugin. No CouchDB, no S3 keys, no config files to tune.

In Obsidian you enter server address, name and password, pick a vault from the list, and you're done.

  • 🖥️ Server: one small Docker container (Go + SQLite, ~27 MB image, tens of MB of RAM). It runs on ZimaOS, a NAS or the cheapest VPS.
  • ✍️ Web editor: read and edit notes in the browser, no Obsidian needed. Changes reach every device within seconds.
  • 🌍 Publishing: turn chosen notes into a public website at /p/<name>/.
  • 🌐 Web admin: users, vaults, sharing, devices, version history, trash and backups. Available in English, Čeština, Slovenčina, Deutsch, Français, Español, Italiano and Polski.
  • 📱 Obsidian plugin: desktop and mobile (iOS/Android), changes arrive within seconds. Same languages as the web admin.
  • 🔀 Safe conflicts: concurrent edits of different parts of a note are merged. When that's not possible, nothing is lost: a copy named … (conflict …) is kept.
  • 💾 Vault backups: for each vault you choose how often to back up and how long to keep backups. Restoring takes one click.

Quick start

A) ZimaOS (or CasaOS)

  1. Open App Store → "+" → Install a customized app, switch to YAML, delete what's there (Ctrl+A, Delete) and paste this (also in deploy/zimaos/docker-compose.yml):

    name: obsisync
    services:
      obsisync:
        image: ghcr.io/jirkacepelka/obsisync:latest
        container_name: obsisync
        restart: unless-stopped
        ports:
          - target: 8080
            published: "8080"
            protocol: tcp
        environment:
          TZ: Europe/Prague
        volumes:
          - type: bind
            source: /DATA/AppData/obsisync/data
            target: /data
    x-casaos:
      architectures:
        - amd64
        - arm64
      main: obsisync
      category: Utilities
      title:
        en_us: SimpleSync
      tagline:
        en_us: Simple self-hosted sync for Obsidian
      icon: https://raw.githubusercontent.com/jirkacepelka/SimpleSync/main/server/internal/web/static/icon.svg
      index: /
      port_map: "8080"
      scheme: http
    
  2. Click Install, then open http://<zimaos-ip>:8080.

  3. Create the administrator account (first-start wizard).

Data lives in /DATA/AppData/obsisync/data.

Access from outside your home network (a phone on mobile data): the easiest option is Tailscale (available in the ZimaOS App Store) or a Cloudflare Tunnel. HTTPS is recommended for iOS; Tailscale provides free HTTPS certificates (tailscale serve).

B) Cheap VPS with your own domain (automatic HTTPS)

A 1 GB RAM VPS with Docker is enough.

# 1) DNS: an A record  sync.example.com → the VPS IP address
# 2) on the VPS:
mkdir obsisync && cd obsisync
curl -O https://raw.githubusercontent.com/jirkacepelka/SimpleSync/main/deploy/docker-compose.caddy.yml
DOMAIN=sync.example.com docker compose -f docker-compose.caddy.yml up -d

Open https://sync.example.com and create the administrator. Caddy obtains the Let's Encrypt certificate by itself.

C) Anything else with Docker

docker run -d --name obsisync -p 8080:8080 -e TZ=Europe/Prague \
  -v $PWD/data:/data --restart unless-stopped ghcr.io/jirkacepelka/obsisync:latest

Updating

Pull the new image and recreate the container (on ZimaOS: the app's settings → update / reinstall). Your data in /data is kept.


Connecting Obsidian

The easy way: download a ready-made vault

In the web admin click Download for Obsidian next to a vault (or Plugin → Download ready-made vault for an empty one). You get a ZIP with a folder that contains the vault's notes and the SimpleSync plugin, already installed and set up for your server and name (no password or token is ever put in the ZIP).

  1. Unzip it, for example into Documents.
  2. In Obsidian choose Open folder as vault and pick the unzipped folder.
  3. Click Trust author and enable plugins.
  4. Enter your password in the window that appears. The vault connects by itself and starts syncing.

Manually: an existing vault or a phone

  1. Install the plugin. In the web admin click Plugin → Download plugin (ZIP), unzip it into <vault>/.obsidian/plugins/ (a simplesync folder appears) and enable Settings → Community plugins → SimpleSync. On a phone, the easiest way is the BRAT plugin with the repository jirkacepelka/SimpleSync.
  2. In the plugin settings enter the server address, name and password, then click Log in.
  3. Pick a vault from the list and click Connect. Or use Create a new vault from this one, which uploads the current vault to the server.

The status bar icon shows the state: ✓ synced, ⟳ syncing, ⚡ server unreachable, ⚠ error. Click it to sync right away. The plugin language follows Obsidian; you can change it in the plugin settings.

What happens when you connect

⚠️ Connecting to a server vault that already has files replaces the content of this Obsidian vault. Nothing is uploaded from this device; local files that differ are moved to Obsidian's trash (.trash). The plugin shows a warning in its settings and asks before connecting. If you want to upload an existing vault, use "Create a new vault from this one" instead.

  • The server vault has content: it always wins. This device becomes an exact copy of the server and nothing is uploaded from it. Local files that differ from the server, or exist only on this device, are moved to Obsidian's trash (.trash), so nothing is lost. An empty or brand-new Obsidian vault can never overwrite the server.
  • The server vault is empty: the content of this device is uploaded to it.
  • If the first sync is interrupted (network drops, app closed), the next sync continues in the same "copy the server" mode.

After the first sync, both directions sync normally.


Web editor

Open a vault in the web admin and click Open notes (or the Notes tab). You get a file tree, an editor and a live preview side by side, so you can write from any browser without installing Obsidian.

  • Saving is automatic, a moment after you stop typing (or Ctrl+S). Saves use the same compare-and-swap commit as the plugin, so they show up on every device within seconds and appear in the version history as name (web).
  • Edits from elsewhere appear in the open note by themselves. If a note was changed on another device while you were typing, the changes are merged line by line; if both sides changed the same line, the other version stays and yours is kept next to it as a … (conflict …).md copy, exactly like on a device.
  • Obsidian syntax in the preview: [[wikilinks]] (with |alias and #heading), embedded images ![[photo.png]], callouts > [!tip], ==highlights==, #tags, task lists, tables and properties (front matter).
  • Files: create, rename and delete notes and folders from the tree (deleted files go to the vault's Trash). Paste or drop images into the editor to upload them next to the note.
  • Typing [[ suggests notes to link. The toolbar and shortcuts (Ctrl+B/I/K) cover the usual formatting; lists continue on Enter.
  • Roles apply: owners and editors can edit, read only members get the reading view.

Publishing

A vault owner can publish notes as a small public website: Vault → Settings → Publishing.

  • Address: the site lives at https://<your server>/p/<address>/.
  • Which notes: either chosen notes (those with publish: true in their properties; the Publish button in the editor toggles it) or a whole folder (empty = the whole vault).
  • Front page: optionally a note to show at the site's root; otherwise a list of the published notes.

Only published notes are reachable. Links to notes that aren't published are shown as plain text, so their names and paths don't leak, and an image or file is served only when a published note links to or embeds it. Visitors need no account. Raw HTML in notes is never rendered, and public pages send a strict Content-Security-Policy.

AI agents (MCP)

The server speaks the Model Context Protocol at https://<your server>/mcp, so an AI agent can work with your notes directly, without a synced local folder: answer questions from your notes, file a daily summary, clean up an inbox, or run on a schedule (for example a scheduled task in Claude). Everything it changes goes through the same sync as the plugin: it reaches your devices within seconds, is kept in the version history as name (agent), and deleted notes land in the vault's Trash.

  • Claude (claude.ai, desktop and mobile app): Settings → Connectors → Add custom connector, paste the address and click Connect. Claude opens this server's sign-in page, where you pick the vault (or all of them) and whether it may write. The server must be reachable from the internet over https (Claude connects from its own servers).
  • Claude Code and other agents: create a token on the AI agents page and send it as Authorization: Bearer <token>, e.g. claude mcp add --transport http simplesync https://<your server>/mcp --header "Authorization: Bearer osa_…".

Tools: list_vaults, list_notes, read_note, search_notes, recent_changes, and with write access create_note, update_note (merges with edits made meanwhile when given the hash from read_note), append_to_note, move_note, delete_note. Obsidian's own files (.obsidian/…) are hidden, and only text files can be written.

A token (or a Claude connection) belongs to one user and never gets more than that user's role: a read-only member stays read-only whatever the token says. Every connection is listed on the AI agents page with when it was last used, and revoking it cuts it off immediately.

Web admin

Section What it does
Overview vaults, disk usage, devices online, alerts about failed backups
Vaults create a vault (name, backup frequency, how long to keep backups, members)
→ Notes the web editor (see above)
→ Files browse folders, preview notes and images, version history with restore, download the whole vault as ZIP
→ Trash deleted files and restoring them
→ Backups list of backups, Back up now, ZIP download, restore a single file or the whole vault
→ Members share the vault with other users: Owner / Editor / Read only; with folder access on, their roles and folders of their own
→ Roles roles that give folders for reading or editing (only when folder access is on, see below)
→ Settings rename, change the backup plan, publishing, folder access, delete the vault
Users create accounts, reset passwords, administrators
Devices every Obsidian login; logging a device out removes its access immediately
AI agents tokens and Claude connections for the MCP endpoint (see above)
Settings how long to keep version history, maximum file size, whether users may create vaults

The language picker is at the bottom of every page.

Folder access

By default a member sees the whole vault. When people should see only part of it, the vault owner switches on Folder access in the vault's Settings. It is off by default and changes nothing until switched on; switching it off makes the whole vault visible to every member again (roles are kept for later).

With folder access on, members who are not owners see nothing until they are given folders:

  • On the new Roles tab, create roles such as Education or Transport. A role is a list of folders, each for Read or Edit, e.g. Education: Education → Edit, Shared → Read. Whole vault can be picked as a folder too.
  • On the Members tab, tick the roles of each member; a member can have several. Under a member you can also add folders of their own, without making a role. Members who were given nothing are marked sees nothing.
  • A member sees every folder given to them, with everything inside. When the same folder is given twice, Edit beats Read. A member whose vault role is Read only never edits. Owners and administrators always see everything.

The server enforces this everywhere: other files do not exist for that member in Obsidian, the web editor, file history, trash, ZIP downloads, links, search or AI agents, and changes outside folders given for editing are refused. Members limited this way do not see Backups, because a backup is a snapshot of the whole vault. When a folder is taken away, the Obsidian plugin moves its files to the Obsidian trash (files the member had edited are kept, but no longer synced); when a folder is given, it arrives with the next sync. Edits in a folder given for reading stay on that device and the status bar says how many were not uploaded.

Folders are given by path. Renaming a folder in the web editor keeps its access, but a rename in Obsidian does not (the server only sees files being deleted and created), so the Roles and Members tabs mark folders that no longer exist. The .obsidian settings folder is a folder like any other: give it for reading if those members should get the shared Obsidian settings. Members need the Obsidian plugin 0.8.0 or newer.

Backups

When creating a vault, the administrator chooses:

  • Backup frequency: off / every hour / every 6 hours / daily / weekly
  • Keep backups for: 7 days / 30 days / 90 days / 1 year / forever
  • optionally also save as ZIP: every backup is additionally written as a standalone ZIP file to data/backups/, handy for copying to another disk

How it works:

  • A backup is a snapshot of the whole vault. Identical file content is stored only once on disk, so backups take almost no extra space.
  • If the vault hasn't changed since the last backup, the scheduled backup is skipped.
  • Old backups are removed according to the retention setting; the newest backup is never deleted.
  • Restoring the whole vault first saves the current state as a "Before restore" backup, then sends the changes to every device like a normal sync.

Backing up the whole server

Everything (database, file contents, ZIP backups) is in the data/ folder. Back up that folder. For a consistent copy of the database while running:

docker exec obsisync obsisync backup-db /data/obsisync-backup.db

Forgotten administrator password

docker exec obsisync obsisync reset-password admin NewPassword123

(If the user doesn't exist, it is created as an administrator.)


Network use and privacy

The SimpleSync plugin communicates only with the SimpleSync server whose address you enter, a server you run yourself. It sends your login once to obtain a device token (the password is not stored), then uploads and downloads the files of the connected vault. To do that it lists all files in the vault and compares them with the server; nothing is sent anywhere else. There is no telemetry, no third-party service and no account with anyone else. Content is protected in transit by HTTPS when the server is reachable over HTTPS; it is not end-to-end encrypted, so whoever runs the server can read the notes stored on it.

Security

  • Every check happens on the server. The plugin only holds a random device token (never the password); the server verifies it and the user's role in the vault on every request. Tokens are stored only as SHA-256 hashes. A device can be logged out in the web admin at any time.
  • Passwords are hashed with Argon2id. At most a few password checks run at once, so login floods cannot exhaust memory, and unknown names take as long as wrong passwords.
  • Login throttling (web admin and plugin): 10 failures per IP address and name, 30 per IP address, and 30 per account from any address, all within 15 minutes. The per-account limit cannot be bypassed with many IP addresses or a forged X-Forwarded-For. Devices and browsers that are already logged in keep working while an account is throttled.
  • Web admin: session cookies are HttpOnly and SameSite=Lax, every form has a CSRF token, pages send a strict Content-Security-Policy and may not be framed, and files from vaults are only ever downloaded (never rendered as HTML/SVG).
  • Paths from devices are validated on the server and again in the plugin, so nothing can be written outside the vault. Files in .obsidian are only synced when you turn that on; only do so in vaults shared with people you trust, because synced plugins run on every device.
  • Transport: use HTTPS when the server is reachable from the internet (Caddy, Tailscale or a Cloudflare Tunnel). The plugin warns before sending a password over plain http:// outside your home network.
  • First start: until the administrator account exists, whoever opens the web admin first can create it. Create it right after installing.
  • Reverse proxies: the client address is taken from X-Forwarded-For only when the connection comes from a local or private address, and then only the entry added by the nearest proxy.

Architecture

Obsidian (desktop / mobile)                 Server (1 Docker container)
┌───────────────────────┐   HTTPS (REST)    ┌────────────────────────────────┐
│ SimpleSync plugin    │◄────────────────►│ SimpleSync server (Go)        │
│  • 3 fields + picker  │   WebSocket       │  • /api/v1  sync               │
│  • sync engine        │◄──────────────────│  • /        web admin          │
│  • 3-way merge        │  ("new revision") │  • SQLite   metadata, history  │
└───────────────────────┘                   │  • blobs/   content (SHA-256)  │
                                            │  • backup scheduler + upkeep   │
                                            └────────────────────────────────┘

How sync works

  • File contents are stored by their SHA-256 hash (content-addressed). This gives deduplication and history, and renames need no re-upload.
  • Every vault has a growing revision number. A device remembers the last revision it saw and fetches only changes after it.
  • For every file, each device remembers the "base" hash: the version it last agreed on with the server. Writes to the server are compare-and-swap: a write only succeeds if the server still has that base version. Otherwise it's a conflict:
    • text files: 3-way merge (changes on different lines are combined),
    • overlapping changes and binary files: the server version wins and the local one is saved as Note (conflict 2026-09-25 1530 jirka).md (with the name of the user whose edit it is),
    • edit vs. delete: the edit wins.
  • Over WebSocket the server only says "the vault has a new revision"; devices then fetch the changes. As a fallback the plugin syncs every minute, 2 s after a file changes, and when the app comes back to the foreground.
  • Paths are normalized to Unicode NFC (macOS/iOS vs. Windows vs. Linux). Paths that differ only in letter case are rejected, because they would collide on Windows/macOS.
  • Safety net: if a sync would delete more than half of the files on the server (for example, the vault didn't load), the plugin asks first.
  • Not synced: .trash/, .git/, other hidden folders, workspace.json and the plugin's own data (token). The .obsidian folder can be enabled with a toggle, and individual plugins can be excluded from it.

API: everything is under /api/v1, authorized with Authorization: Bearer <device token>:

Endpoint Purpose
POST /auth/login name + password → device token (the password is not stored on the device)
GET /vaults, POST /vaults the user's vaults / create one
GET /vaults/{id}/changes?since=REV changes since a revision
POST /vaults/{id}/blobs/missing which content the server doesn't have yet
PUT / GET /vaults/{id}/blobs/{sha256} upload / download content
POST /vaults/{id}/commit a batch of changes (compare-and-swap)
GET /vaults/{id}/ws WebSocket notifications

Repository layout

server/     Go server (cmd/obsisync, internal/{store,api,web,backup,blobs,auth,hub,i18n,markdown,textmerge})
plugin/     Obsidian plugin (TypeScript); src/engine is Obsidian-independent and tested
deploy/     docker-compose for home network, VPS with Caddy, and ZimaOS
Dockerfile  multi-arch image (amd64 + arm64) with the server and the plugin

Development

# server
cd server && go test ./... && go run ./cmd/obsisync    # http://localhost:8080, data in ./data

# plugin (tests start a real server and simulate several devices)
cd plugin && npm ci && npm test && npm run build       # output in plugin/dist

Translations: the web admin uses server/internal/i18n/locales/<lang>.json, the plugin uses plugin/src/i18n/<lang>.ts. English is the source; missing keys fall back to English.

Releases: every push to main makes GitHub Actions build the Docker image ghcr.io/jirkacepelka/obsisync (latest and the version from manifest.json) and a GitHub release with the plugin files. To publish a new version, bump version in manifest.json, plugin/manifest.json and versions.json.

Environment variables (optional)

Variable Default Meaning
TZ UTC time zone for displayed times (e.g. Europe/Prague)
OBSISYNC_DATA /data data folder
OBSISYNC_ADDR :8080 listen address and port
OBSISYNC_BACKUP_DIR $OBSISYNC_DATA/backups where ZIP backups go

License

MIT

HealthExcellent
ReviewSatisfactory
About
Sync Obsidian vaults to a compact self-hosted server for desktop and mobile with near-real-time changes. Manage users, vaults, version history, trash and backups via a web admin; get safe conflict merging and automatic conflict copies when merges fail.
SyncingBackup
Details
Current version
0.9.0
Last updated
4 days ago
Created
2 months ago
Updates
15 releases
Downloads
225
Compatible with
Obsidian 1.4.0+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Author
Jiří Čepelka Jiří Čepelka jirkacepelka
GitHubjirkacepelka
  1. Community
  2. Plugins
  3. Syncing
  4. SimpleSync

Related plugins

YAOS

Simple real-time sync powered by your own Cloudflare Worker.

GitHub

GitHub Sync

Sync vault to personal GitHub.

Differential ZIP Backup

Back our vault up with lesser storage.

GitHub

GitHub Gitless Sync

Sync a GitHub repository with vaults on different platforms without requiring git installation

Yandex Disk Sync

Synchronize your vault with Yandex Disk. Supports bidirectional sync, conflict resolution, and works on mobile.

Settings profiles

Create various global settings profiles, that sync between vaults.

Baidu Netdisk Sync

Cross-platform bi-directional synchronization with Baidu Netdisk for your vaults.

Remotely Save

Sync notes between local and cloud with smart conflict: S3, Dropbox, webdav, OneDrive, Google Drive, Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.

Lockstep Sync

Sync your Obsidian vault between desktop, iOS and Android through your own server. Self-hosted, end-to-end encrypted, free and open source: no cloud, no subscription.

Remotely Sync

Security fixes for the remotely-save unofficial plugin allowing users to synchronize notes between local device and the cloud service. Not backwards compatible.