About
I started pinemere in late 2025 after losing a directory of scanned negatives to a botched rsync invocation. The --delete flag and a swapped source/destination wiped about 1,400 files from my backup server before I noticed. The originals were on a drive that had already been reformatted.
I had been using rsync for years and never thought twice about it. That incident made me realize I wanted something with a content-addressed store — where deleting a file on the source side doesn't immediately purge it from the target, because the target knows the content independently of the path. A system where "sync" means "make sure you have everything I have" rather than "make the target look exactly like the source."
Why not Syncthing / restic / rclone
Syncthing is excellent for bidirectional real-time sync but it doesn't do dedup across directories. If you have three copies of the same photo library in different paths, Syncthing stores and transfers all three. Restic does content-addressed backup beautifully, but it's a backup tool — I wanted live sync with partial restore and streaming diffs, not snapshot-based archival. Rclone is the Swiss army knife, but it's fundamentally a copy tool with no dedup layer.
Pinemere fills a specific gap: one-directional sync (like rsync) but with content-addressed dedup (like restic) and streaming diffs (like neither). It's not trying to replace any of those tools. I use rclone alongside it for cloud targets.
The name
"Pinemere" is a portmanteau of "pine" and "mere" (an Old English word for lake or pond). I grew up near a small glacial lake surrounded by Scots pines in Latvia, and the image of still water reflecting tall trees felt right for a tool that mirrors file trees. It's also easy to type, which matters more than it should for something you run thirty times a day.
Technical details
Written in Rust, using tokio for async I/O and blake3 for hashing. The dedup layer is a custom Merkle tree built on variable-size content-defined chunks (Rabin fingerprinting with a target block size of 64 KB). The protocol is a simple length-prefixed binary format over TCP, no TLS by default — I assume the transport layer handles encryption if needed (SSH tunnels, WireGuard, etc.).
The manifest format is a flat SQLite database per pool. I tried a custom binary format first and regretted it within a week. SQLite is everywhere, it's inspectable, and pinemere stat is just a fancy SELECT.
Source code will be published once v0.3.0 reaches a state I'm not embarrassed by. Until then, binaries are available on the install page.
Contact
Email: hello at pinemere.website. I read everything but reply slowly.