Core Concepts
Understand the fundamentals.
The vocabulary you need to read the rest of the docs.
Convergent encryption
Every file is encrypted with a key derived deterministically from its plaintext (HMAC-SHA256 + AES-256-GCM with the nonce derived from the same hash). Property: identical input → identical ciphertext → automatic deduplication across users + retransmission safety.
The trade-off: an attacker who already has a candidate plaintext can verify whether you've stored it. For most threat models (your photos, your documents) that's fine; for "is this person storing X" attacks specifically you'd want random-nonce mode (planned, not shipped).
Replication factor
Each vault has replication_factor: N. The mesh keeps trying to land
each block on at least N reliable peers through periodic gossip. RF
is achieved per-block, not per-vault — small files don't pay the cost
of large ones.
A reliable node is one whose config declares reliable: true. Phones
default to false — they help seed but don't count.
Capacity pooling
A vault's usable space is the sum of its trusted nodes' free disk, not one node's. Upload through a node that's full and the new file's blocks are placed on a peer that has room (chosen by free space); that peer becomes the holder. You get "out of space" only when the whole reachable mesh is full. The node you wrote through still lists and serves the file — it fetches the blocks from the holder on demand.
This pools capacity across files. And when a single file is too big for
any one node, it's sharded: split into contiguous runs of blocks
that are placed on different nodes, so one object can exceed any single
disk as long as the mesh holds it collectively. Small files that fit on one
node aren't sharded — sharding kicks in only when nothing else fits. Reads
gather each shard's blocks from whichever node holds them, transparently.
Tune the shard size with node.shard_size_bytes (default 1 GiB; set
negative to disable and fall back to "out of space" for oversize files).
Only blocks-mode vaults pool — a vault with a storage_path keeps its
plaintext locally as the source of truth, so its writes stay on that node.
Tune placement with node.placement_mode (local-first default, or
balanced to spread every file across the mesh from the start).
Trusted vs. untrusted
Trust = "does this node have the vault key". Untrusted nodes happily store ciphertext blocks and participate in replication; they never see plaintext. This is what lets a €5/month VPS be redundancy without needing to trust the provider.
Vaults, blocks, hash-chains
- Vault = a name + a key + a policy (RF, storage path, type).
- Block = a chunk of ciphertext addressed by SHA-256. Sizes: ≤ 512 KiB for small files, 4 MiB for large.
- Hash-chain versioning = each new version of a file carries a
parent_hashpointer to the previous version. Same file edited on two nodes simultaneously → the mesh detects the fork on next gossip. Whether old versions stay restorable is a per-node decision: a folder-backed node keeps them withkeep_history: true(storing real ciphertext blocks alongside the plaintext), bounded by ahistory_retentionpolicy (keep all / last N versions / last N days / staggered Syncthing-style thinning). So a phone can stream files, a laptop hold a plain copy, and a NAS keep the deep history — all of the same vault. - Ignore rules = the folder scanner skips junk and VCS files by
default (dotfiles,
Thumbs.db, editor scratch) and honours per-vault gitignore-style patterns viaignore_globsor a.holdignorefile in the folder.
Mesh topology + gossip
There is no central directory. Every node holds a partial view of the
mesh, gossipped via the /meshhold/hello/1.0 protocol. A first
handshake brings back every other node currently online — any of them
can be your bootstrap on the next reconnect.
Three encryption layers
- Swarm key — 256-bit shared secret; without it, nodes can't even open a libp2p connection.
- Per-connection Noise session key — fresh on every TCP stream, forward-secret, ChaCha20-Poly1305 AEAD.
- Per-vault / chat / tunnel / agent content key — independently shareable; one capability doesn't unlock another.
See the diagram on the home page for the visual.