5 KiB
Trilium Incremental Markdown Backup
A lightweight, incremental backup tool for TriliumNext that exports your notes as individual Markdown (.md) files.
Instead of exporting your entire vault every time, this script queries the ETAPI to download only the notes that have been modified since the last run. Large vaults are backed up in seconds after the initial full export.
No plugins or Node.js required—just a single Python script, the Trilium ETAPI, and a cron job.
🚀 Features
- Incremental Backups: Skips notes whose
dateModifiedhasn't changed since the last backup timestamp. - Folder Hierarchy: Automatically organizes your
.mdfiles into folders that mirror your Trilium note tree. - Smart Filenames: Saves files as
Note Title [note_id].mdto completely prevent name collisions (e.g., when two notes share the same title in the same folder). - Multi-Type Support: Backs up
text,code, andmermaidnotes out of the box. - YAML Frontmatter: Each
.mdfile includes a frontmatter block withtrilium_id,created, andmodifiedtimestamps, making it easy to diff versions or re-import later. - Resilient: Features an automated retry queue. If a note fails to download (e.g., network error), it gets logged in the state file and is automatically reprocessed on the next run.
- Fast: Utilizes an in-memory metadata cache to drastically reduce redundant API calls when building hierarchical folder paths.
📋 Requirements
System (Debian/Ubuntu)
sudo apt update
sudo apt install python3 python3-pip
Python Libraries
The script requires the requests library:
pip install requests --break-system-packages
Note: On Ubuntu 23+ or Debian 12+, the
--break-system-packagesflag is required if installing globally. Alternatively, use a virtual environment:python3 -m venv .venv source .venv/bin/activate pip install requests
⚙️ Setup
- Clone this repository or download the
trilium_backup_incremental.pyscript. - Edit the three configuration variables at the top of the script to match your environment:
SERVER = "http://localhost:8080" # Your Trilium server address
TOKEN = "YOUR_ETAPI_TOKEN" # Settings → ETAPI → Generate token
BACKUP_DIR = Path("/home/youruser/Backup_MD") # Your destination folder
(To get your ETAPI token in TriliumNext: Go to Menu → Options → ETAPI and click Generate new token).
💻 Usage
First Run (Full Backup)
On its first execution, the script fetches all supported notes and builds the local directory structure.
python3 trilium_backup_incremental.py
Example Output:
First backup — exporting all notes...
347 note(s) to process...
[1/347] saved: Home
[2/347] saved: Journal
...
✓ Completed: 347 note(s) saved, 0 skipped.
Backup at: /home/youruser/Backup_MD
Subsequent Runs (Incremental)
On later runs, the script checks the hidden .backup_state.json file and only fetches what has changed (plus any previously failed downloads).
Example Output:
Last backup: 2026-04-20T14:32:00.123456+00:00
Searching for notes modified since then...
12 note(s) to process...
[1/12] saved: Meeting notes 2026-04-21
[2/12] no changes: Home
...
✓ Completed: 1 note(s) saved, 11 skipped.
📁 Backup Folder Structure
Backup_MD/
├── .backup_state.json ← internal state file & retry queue (hidden)
├── Home [abc123XYZ].md
├── Journal/
│ ├── 2026-04-20 [def456UVW].md
│ └── 2026-04-21 [ghi789RST].md
├── Projects/
│ ├── Project A [jkl012MNO].md
│ └── Project B [pqr345LMN].md
└── ...
Inside each .md file:
---
title: "Meeting notes 2026-04-21"
trilium_id: ghi789RST
created: 2026-04-21 09:00:00.000Z
modified: 2026-04-21 11:32:00.000Z
---
Note content here...
⏱️ Scheduling Automatic Backups (Cron)
To run a backup every day at 2:00 AM, open your crontab:
crontab -e
Add the following line (adjusting paths to match your system):
0 2 * * * python3 /home/youruser/scripts/trilium_backup_incremental.py >> /home/youruser/trilium_backup.log 2>&1
The >> ...log 2>&1 portion captures all script output into a log file so you can review your backup history.
⚠️ Notes and Limitations
- Text-focused: Backs up
text,code, andmermaidnotes. Canvas notes, renderNotes, relation maps, and other non-text elements are skipped. - Attachments: This is a text-only backup; image attachments and files are not downloaded. If you need attachments, use the native Trilium export feature.
- HTML → Markdown conversion: Trilium stores text notes internally as HTML. The script performs a basic conversion (handling headings, paragraphs, and line breaks).
- Append-only: The script currently does not delete local
.mdfiles if the corresponding note is deleted inside Trilium.