English
Performance
How fast is a vault sync, and how big can your vault get before you feel it? We measured the pushNotes mutation — the call the Obsidian plugin and the CLI make on every sync — on vaults of 10 to 10 000 notes.
The charts below are live datachart blocks reading the raw benchmark CSV from this vault — the same feature you can use for your own data.
Method
- Each run starts a fresh server with an empty SQLite database, pinned to 1 or 4 CPU cores (
taskset+GOMAXPROCS). - Synthetic notes of ~500 bytes: frontmatter, headings, a wikilink, a list, a code block.
- Initial push — all N notes in one
pushNotescall (one write transaction). - 1 note — a typical small sync: one changed note pushed into a vault of N notes (median of 3).
- 10% of vault — a batch sync: N/10 changed notes in one push (median of 3).
- Memory is the server's resident set size (RSS) after the run; peak from
/proc. - Benchmark script:
scripts/bench-pushnotes.shin the repository.
Important context: while a push is being processed, the server holds the database write lock — other writers (background jobs, other pushes) wait in line. So "push time" here is also "how long the database is locked".
Initial push: whole vault in one call
{
"data": { "source": "frontmatter", "ref": "chart_bench" },
"config": {
"title": { "text": "Initial push, ms (less is better)" },
"tooltip": { "trigger": "axis" },
"legend": {},
"xAxis": { "type": "category", "name": "notes" },
"yAxis": { "type": "log", "name": "ms" },
"series": [
{ "type": "bar", "name": "1 core", "encode": { "x": "notes", "y": "initial_1c" } },
{ "type": "bar", "name": "4 cores", "encode": { "x": "notes", "y": "initial_4c" } }
]
}
}
Scaling is close to linear: ~1.2 s for 1 000 notes on one core, ~14 s for 10 000. Four cores cut that roughly in half — note rendering parallelizes, the database writes do not.
Incremental sync: the everyday case
{
"data": { "source": "frontmatter", "ref": "chart_bench" },
"config": {
"title": { "text": "Incremental push, ms (less is better)" },
"tooltip": { "trigger": "axis" },
"legend": {},
"xAxis": { "type": "category", "name": "vault size, notes" },
"yAxis": { "type": "log", "name": "ms" },
"series": [
{ "type": "line", "name": "1 note, 1 core", "encode": { "x": "notes", "y": "incr1_1c" } },
{ "type": "line", "name": "1 note, 4 cores", "encode": { "x": "notes", "y": "incr1_4c" } },
{ "type": "line", "name": "10% of vault, 1 core", "encode": { "x": "notes", "y": "incr10p_1c" } },
{ "type": "line", "name": "10% of vault, 4 cores", "encode": { "x": "notes", "y": "incr10p_4c" } }
]
}
}
This is what you feel day to day: you edit a note, the plugin pushes it. Even at 10 000 notes a single-note push takes ~0.4 s on one core and ~0.2 s on four. The renderer caches unchanged notes, so the cost grows with vault size (re-indexing), not with how much you changed — pushing 1 000 changed notes (10% of a 10 000-note vault) takes ~2.3 s on one core, far from 1 000 × the single-note cost.
Memory
{
"data": { "source": "frontmatter", "ref": "chart_bench" },
"config": {
"title": { "text": "Server RSS after sync, MB" },
"tooltip": { "trigger": "axis" },
"legend": {},
"xAxis": { "type": "category", "name": "notes" },
"yAxis": { "type": "value", "name": "MB" },
"series": [
{ "type": "bar", "name": "RSS, 1 core", "encode": { "x": "notes", "y": "rss_1c" } },
{ "type": "bar", "name": "RSS, 4 cores", "encode": { "x": "notes", "y": "rss_4c" } },
{ "type": "line", "name": "peak, 1 core", "encode": { "x": "notes", "y": "peak_1c" } },
{ "type": "line", "name": "peak, 4 cores", "encode": { "x": "notes", "y": "peak_4c" } }
]
}
}
The server keeps rendered notes in memory: ~80 MB for a hundred notes, ~180 MB for a thousand, ~1 GB for ten thousand. Plan your hosting accordingly — a 1 GB VPS comfortably serves vaults up to a few thousand notes.
Raw numbers
| Vault | Initial push 1c / 4c | 1 note 1c / 4c | 10% batch 1c / 4c | Peak RSS 1c / 4c |
|---|---|---|---|---|
| 10 | 40 / 8 ms | 4 / 2 ms | 4 / 2 ms | 68 / 69 MB |
| 100 | 113 / 81 ms | 6 / 8 ms | 13 / 10 ms | 83 / 80 MB |
| 1 000 | 1.2 / 0.5 s | 39 / 22 ms | 96 / 62 ms | 182 / 149 MB |
| 10 000 | 13.8 / 6.8 s | 382 / 224 ms | 2.3 / 0.7 s | 1186 / 902 MB |
Measured 2026-06-11 on a 12-core ARM64 dev machine restricted with taskset, SQLite in WAL mode, single server process. Your absolute numbers will differ; the shape of the curves will not.
What this means for you
- Vaults up to ~1 000 notes: everything is instant — syncs are tens of milliseconds.
- ~10 000 notes on a small server: everyday syncs are still sub-second, but the first push of the whole vault takes ~14 s on one core. During that window the database is locked for other writers; on very large vaults prefer an initial import during quiet hours.
- More cores help rendering, not locking: a 4-core server halves big-push times. The lock is held for the whole push either way, so many concurrent writers gain less than the raw numbers suggest.