Configuration

The frostvex.toml reference.

Frostvex looks for a config file in this order, first match wins:

  1. --config on the command line
  2. $FROSTVEX_CONFIG environment variable
  3. ./frostvex.toml in the current directory
  4. ~/.config/frostvex/config.toml

If none exists, frostvex runs with a built-in default that matches what's described below as "default". You don't need a config file to get started — but you'll want one as soon as you have more than a couple of pools.

A complete example

# frostvex.toml — annotated

[transport]
listen   = "0.0.0.0:7423"          # QUIC bind address
external = "backup.example.org:7423" # what peers see
keepalive_secs = 25

[parity]
scheme  = "reed-solomon"
data    = 8            # data shards per stripe
parity  = 4            # parity shards per stripe
chunk_size_kb = 128

[bandwidth]
upload_kbps   = 8000     # cap upload at 1 MB/s
download_kbps = 0        # 0 = unlimited
schedule = [
  { from = "00:00", to = "06:00", upload_kbps = 0 },
]

[peers]
mdns          = true
exchange_path = "~/.config/frostvex/peers.toml"
trust_on_first_use = false

[log]
level = "info"
file  = "/var/log/frostvex.log"

[transport]

keytypedefaultnotes
listenstring"0.0.0.0:7423"UDP/QUIC bind. Empty disables incoming connections (client-only mode).
externalstring""What we advertise to peers. Useful behind NAT or with a stable hostname.
keepalive_secsint25QUIC keepalive interval. Lower it on aggressive carrier-grade NAT (mobile).
max_streamsint32Concurrent streams per peer. Bumping this rarely helps.

[parity]

Reed-Solomon is the only supported scheme today. The defaults (8 data + 4 parity, 128 KB chunk) survive any 4 chunks lost per stripe and have ~50% storage overhead. If you only care about detection — not reconstruction — set parity = 0 and you'll save the disk but lose the ability to repair from a single peer.

keytypedefaultnotes
schemestring"reed-solomon"Only "reed-solomon" for now. "none" disables.
dataint8Data shards per stripe. Range 4..16.
parityint4Parity shards. Range 0..8.
chunk_size_kbint128Smaller chunks help on tiny files; larger help on big ones. Power of 2.

[bandwidth]

Caps are enforced at the QUIC congestion-controller layer, so they're soft limits — frostvex won't go significantly above them but momentary spikes are possible. Schedule windows let you uncap overnight.

keytypedefaultnotes
upload_kbpsint00 = unlimited.
download_kbpsint00 = unlimited.
schedulearray[]List of {from, to, upload_kbps, download_kbps} windows. Times are local TZ.

[peers]

keytypedefaultnotes
mdnsbooltrueDiscover peers on the LAN via mDNS.
exchange_pathpath"~/.config/frostvex/peers.toml"Persistent peer list. Auto-edited by frostvex peers add.
trust_on_first_useboolfalseIf true, accept any peer's pubkey on first contact. Convenient for home networks; do not enable if you sync over the open internet.
relaystring""Optional fallback relay URL for hard-NAT scenarios.

[log]

keytypedefaultnotes
levelstring"info"One of error|warn|info|debug|trace.
filepath""If empty, stderr only. Rotated externally — frostvex doesn't manage rotation.
formatstring"text""text" for humans, "json" for log aggregators.

Environment overrides

Any setting can be overridden by an env var of the form FROSTVEX_<SECTION>_<KEY>:

$ FROSTVEX_BANDWIDTH_UPLOAD_KBPS=4000 frostvex sync ./photos --to backup:/srv/

Useful inside containers and systemd unit files where you don't want to ship a config file.

Per-pool overrides. Settings inside a pool's .frostvex/pool.toml override the global config for that pool only. Use this when one pool has special bandwidth needs.