Skip to main content

Performance Architecture

Basalt is engineered to compete directly with Obsidian and outperform it at extreme scale. Every architectural decision is guided by three non-negotiable performance targets:

  • Sub-16ms Keystroke Latency: Typing in the editor must never drop below 60fps, even in files with thousands of links and complex decorations.
  • <800ms Time-to-Interactive (TTI): Opening a massive vault must present an interactive editor in less than a second.
  • <150ms Full-Text Search: Querying across 5,000 to 25,000 notes returns ranked results almost instantly.

The Super-Large Vault Philosophy (≥25k Notes)​

Testing software on small vaults of 500 notes produces misleading benchmarks. Power users frequently manage personal knowledge bases containing 25,000 to 50,000 notes, rich link graphs, and thousands of task items.

In Basalt:

  • Performance claims and CI benchmark gates are evaluated against $\ge 25,000$-note fixtures.
  • If a feature passes on 1k notes but degrades at 25k scale, it is considered broken.

Standing Performance Systems​

1. Instant Two-Tier Boot (ADR-046)​

Traditional PKM apps re-scan the vault directory on startup, blocking the user while spinning through tens of thousands of files. Basalt uses a decoupled two-tier boot strategy:

  • Tier 1 (Instant Cache Mount): Upon launch, the Rust backend reads a compact pre-compiled bincode cache from disk into memory in <100ms. The file tree, active notes, and tags appear instantly.
  • Tier 2 (Background Sync): A background Rayon thread pool scans file modification times (mtime), reparsing only the specific files that changed while Basalt was closed.
App Launch
│
├── Tier 1 (<100ms) ────────► UI Rendered & Interactive (bincode cache)
│
└── Tier 2 (Background) ────► Rayon mtime scan & incremental diff reindex

2. Zero-AST Scanner with SIMD (ADR-041)​

Constructing full Abstract Syntax Trees (ASTs) for thousands of markdown files consumes hundreds of megabytes of RAM and triggers heavy garbage collection.

Basalt uses a custom zero-AST byte scanner:

  • Utilizes SIMD instructions (memchr3) to find structural tokens (#, [[, - [, ---) directly in raw UTF-8 byte buffers.
  • Extracts tags, links, headings, and task signifiers in a single linear pass without allocating intermediate syntax node objects.

3. Single-Pass Editor Decoration Pipeline (ADR-019, ADR-040)​

CodeMirror 6 live-preview widgets (math, tags, checklists, callouts, embeds) are rendered in a single unified decoration pass. Multiple independent plugin extensions that repeatedly traverse visible viewports during typing are replaced by one consolidated state field, guaranteeing input latency stays under 16ms.

4. Background Native Compute​

All compute-intensive operations run on native OS worker threads in Rust:

  • Tantivy & Nucleo Search: Full-text indexing and fuzzy matching execute off-thread.
  • Graph Simulation: Velocity Verlet physics calculations run in background threads or WASM without stealing animation frames from the browser shell.

Profiling & Bottleneck Hunting​

Basalt includes built-in diagnostic and benchmarking tooling for catching regressions:

  • bun run dev:watchdog — Automatically tracks main-thread frame times and warns if any event handler blocks longer than 16ms.
  • bun run dev:editor-benchmark — Measures live typing and scrolling latency across synthetic documents up to 100,000 words.
  • Phase timings via editorBenchmarkState.debug to isolate exact millisecond costs between keystroke dispatch, DOM mutation, and layout paint.