← julian lupu

TitanSync v0.15.0

github.com/monological/titansync

Peer-to-peer file sync that keeps a folder identical across your devices. No server holds your files. A relay provides peer discovery and issues short-lived locks; it never stores or reads file content. Devices connect directly over libp2p with NAT hole-punching, falling back to a relayed circuit only when no direct path opens.

Statue of Atlas holding up the world

Architecture

The engine is four layers. Reconcile detects that a file is out of date, encoding determines how to describe the difference, sourcing locates the missing bytes and the peers holding them, and the content substrate cuts and names bytes so they can be deduplicated and pulled from several peers at once.

L3 L2 L1 L0 RECONCILE ENCODING SOURCING CONTENT what changed? how to express a change compactly? which bytes, and from whom? how is content cut and named? vector clocks · manifests · dirty-drain · Merkle summary FULL · librsync-delta · block-patch whole-file dedup · swarm fetch FastCDC · chunk-hash identity · content-addressed store · availability-by-hash

Reconcile

Encoding

Sourcing and content

Trust

Testing

Measured

Lab suite on libvirt VMs at 1 vCPU and 1–1.5 GB RAM each.

Scenario Result Control
1,200 small files across a full mesh (7,200 placements) 31s, ~200/s n/a
128 MiB file pushed to every peer 10.9s, 14.3 MiB/s n/a
35,946 files, 30 minutes of writes (15 peers) converged, 642 MB RSS n/a
Rejoining peer pulls 128 MiB from 5 sources 29.5s 39.0s
Idle reconcile round, 3,005-file tree 6.6 KB 485 KB
Manifest bytes over that whole run 26.0 MB 155.2 MB
Catch-up scope after reconnect, 12,014-entry tree 8 entries 12,014
32 MiB file after a 4 MiB mid-file edit 3 of 8 chunks 8 of 8

Control is the same run with that optimization switched off.

Placing one file costs 0.092 ms in a 12k-entry tree and 0.119 ms at 30k, so the apply path is flat in tree size rather than linear.