Skip to content
🚧 Early alpha — building the foundation. See the roadmap →

File-based graph databases

Updated

What kind of database is an Obsidian vault?

Section titled “What kind of database is an Obsidian vault?”

When Crosswalker generates folders and notes with frontmatter properties and WikiLinks, it’s building a file-based graph database. Understanding this helps explain both the power and the limitations of the approach.

An Obsidian vault is a hybrid data model combining concepts from three database paradigms: property graphs, document stores, and file-based databases.

A property graph is a directed, labeled multigraph where both nodes and edges can have key-value properties.

Formal structure:

G = (V, E, ρ, λ, σ)
where:
  V = set of vertices (nodes)
  E = set of edges
  ρ: E → V × V (edge endpoint mapping)
  λ: V ∪ E → Σ (labeling function)
  σ: V ∪ E → Properties (property assignment)

Crosswalker’s implementation:

  • Nodes (V): Markdown files in generated folders (one per imported concept — e.g. a framework control, technique, or safeguard)
  • Edges (E): WikiLinks between notes (crosswalk relationships, hierarchy links)
  • Properties (σ): YAML frontmatter on each file
  • Labels (λ): Folder location + the top-level kind frontmatter field (absent = concept note; junction-note; crosswalk-edge) + tags tag paths. Note that _crosswalker is the provenance block only — it is additionalProperties: false and carries no node-type field, so labels never come from inside it.
ConceptNeo4jMongoDBObsidian Vault
Node/DocumentNode in node storeBSON documentMarkdown file
Edge/RelationshipRelationship storeManual referencesWikiLink
PropertiesProperty storeJSON fieldsYAML frontmatter
Collection/TableLabelsCollectionsFolders
Primary keyInternal ID_id fieldFile path
Foreign keyRelationship$ref / manual[[WikiLink]]
Query languageCypherMQLBases filters, formulas, and views
IndexNative indexesB-tree indexesObsidian cache + folder structure
TransactionsACID transactionsACID (single doc)None
Graph traversalNative O(1)Manual joinsWikiLink following

Denormalization is the deliberate introduction of redundancy into a data model to optimize read performance at the cost of write complexity.

In Crosswalker’s output:

# Source of truth: the crosswalk link in the note
nist_csf.maps_to:: [[AC-2]]

# Derived: AC-2.md's backlinks show this note links to it
# (Obsidian computes this automatically from WikiLinks)

When Crosswalker generates both forward links (note A references note B) and frontmatter properties that duplicate relationship data, it creates a stored denormalized relationship projection for quick access. Because the projection is persisted in files, re-import must keep every copy in sync with its authoritative relationship data.

This is the denormalization tax: every re-import must update all copies, or the data becomes inconsistent. See data model resilience for strategies.

In graph databases, edges can be traversed in both directions:

  • Forward pointer: Source note links to target (maps_to:: [[AC-2]])
  • Reverse pointer: Target note’s backlinks show incoming references (Obsidian computes this)

Frontmatter arrays function as adjacency lists — each note stores a list of its connections:

related_controls:
  - "[[AC-1]]"
  - "[[AC-3]]"
  - "[[AC-5]]"

This enables efficient local queries (“what does this control relate to?”) without scanning all files.

Obsidian Bases provides live views over the file graph: filters, formulas, grouping, and summaries are evaluated from current vault data when the view loads. They are not materialized views because the result is not persisted.

A materialized snapshot exists only when Crosswalker writes a query result to a Markdown or other durable output artifact. That snapshot can travel without the query runtime, but it can become stale and must record how and when it was produced.

AdvantageDisadvantage
Human-readable (plain markdown)No ACID transactions
Git-friendly (version control)No built-in constraints
Portable (copy the folder)No query optimization
No server neededManual relationship maintenance
Works offlineNo referential integrity
Obsidian-native (graph view, backlinks, search)Eventual consistency only

Crosswalker generates a file-based graph database every time it imports an ontology (e.g. a compliance framework). Understanding this model explains:

  1. Why re-import is complex — updating persisted, denormalized relationship projections across hundreds of files requires careful coordination. See ontology evolution.
  2. Why crosswalk links can become stale — no foreign key constraints mean broken links accumulate silently. See constraint enforcement.
  3. Why frontmatter-first is the right approach — Obsidian Bases can query frontmatter but not inline fields, making YAML properties the most queryable storage location.
  4. Why the _crosswalker metadata exists — it provides the schema versioning and provenance tracking that file-based systems lack natively.

  • Robinson, Webber, Eifrem — “Graph Databases” (O’Reilly, 2015)
  • Codd, E.F. — “A Relational Model of Data for Large Shared Data Banks” (1970)