Skip to content

feat: SurrealDB as storage backend for Obsidian sync #125

Description

@diebugger-tech

feat: SurrealDB as storage backend for Obsidian↔dot-skill sync

Follow-up to #124 (Obsidian Vault — bidirectional live sync).

The problem with flat files

The current proposal in #124 uses messages.txt + docs/*.md as output.
This works for one-shot import — but for a living skill that stays in sync
with the vault, flat files have limits:

  • No graph traversal — wikilinks are resolved to plain text, connections lost
  • No vector search — semantic queries over notes not possible
  • No time travel — no history of how knowledge evolved
  • Slow at scale — 10k+ notes make file-based search sluggish

SurrealDB as the answer

SurrealDB is a multi-model database (documents + graph + vectors) that runs
embedded or as a local server. It maps perfectly to Obsidian's structure:

Obsidian Note    → SurrealDB record (note table)
[[Wikilink]]     → SurrealDB graph edge (links table)
Tags             → SurrealDB index
Vault sync       → SurrealDB persistent storage

Proposed architecture

Obsidian Vault
     │
     │  watch (inotify / fsevents)
     ▼
obsidian_vault_collector.py  ← existing (PR #124)
     │
     ├── docs/*.md            ← flat file output (unchanged)
     │
     └── SurrealDB            ← NEW: optional --surreal flag
          ├── note table      (title, body, path, tags)
          └── links table     (graph edges from wikilinks)

The SurrealDB output is additive — flat files remain untouched.
Enable with a single flag:

python3 tools/obsidian_vault_collector.py \
  --vault ~/ObsidianVaults/Andreas/ \
  --name "Andreas" \
  --surreal http://127.0.0.1:8000

What this unlocks

Graph queries — find all notes that link to a concept:

SELECT <-links<-note.title FROM note WHERE title = "SurrealDB";

Vector search — semantic similarity over vault (future):

SELECT title FROM note WHERE embedding <|5|> $query_embedding;

Time travel — vault state at any point in time:

SELECT * FROM note VERSION "2026-03-01T00:00:00Z";

Agent memory — dot-skill reads from SurrealDB instead of flat files,
stays current without manual re-import.

Implementation status

A working PoC exists:

  • obsidian_vault_collector.py extended with --surreal flag
  • AsyncSurreal client (surrealdb Python SDK v2.0.0)
  • Notes and wikilink graph imported into local SurrealDB instance
  • Tested on a 57-note vault

Next steps:

  • obsidian_vault_writer.py — write dot-skill output back as SurrealDB records
  • Watch mode — inotify triggers re-sync on vault changes
  • Rust binary rewrite for performance (obsidian-surreal-importer)

NixOS deployment

# home.nix
home.packages = with pkgs; [ surrealdb surrealist ];

systemd.user.services.surrealdb-vault = {
  description = "SurrealDB for Obsidian vault";
  wantedBy = [ "default.target" ];
  serviceConfig.ExecStart =
    "${pkgs.surrealdb}/bin/surreal start file://%h/.local/share/surrealdb/obsidian";
};

One home-manager switch — SurrealDB runs as a user service, always available.

Happy to contribute

I can submit a PR with the extended collector if the architecture looks right.
The PoC is working locally on NixOS with SurrealDB 2.3.10.

/cc @titanwings

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions