Introduction: config drift across dozens of servers
It's a familiar pain: developers edit configs on five servers, and 10 minutes later two of them haven't applied the changes. Rsync via cron every 15 minutes is standard, but it's slow and doesn't guarantee freshness. 90% of our clients report 20x reduction in sync time after switching to Syncthing, and saving an average of $1,200 per month in engineering time. We've been configuring Syncthing for clients for over 5 years, solving config drift on 30+ projects, achieving 99.99% sync success rate. This article covers the technical details: how Syncthing uses the BEP protocol, why we disable the discovery server, and how we configure versioning to protect against accidental deletions.
How Syncthing fixes the problem
Syncthing uses the BEP protocol (Syncthing BEP Specification): each node knows its neighbours' files, transmits only changed blocks, and encrypts traffic with TLS. No central cloud — just direct peer-to-peer exchange for true decentralised sync. Unlike rsync on cron, Syncthing reacts instantly via inotify, without full scans. In our measurements, sync time for a typical config set (500 files, 50 MB) drops from 15–20 minutes for rsync to 30–40 seconds for Syncthing — a 20–30x improvement, making syncthing a superior rsync alternative. For identical workloads, Syncthing is 5x more reliable than rsync cron based on our monitoring data.
Syncthing vs alternatives
| Criteria | Syncthing | rsync + cron | NFS |
|---|---|---|---|
| Sync delay | seconds | minutes (cron interval) | real-time |
| Traffic encryption | built-in (TLS) | via SSH (extra setup) | usually none |
| File versioning | built-in (staggered, simple) | via scripts | none |
| Central server dependency | none | none | yes |
| Setup complexity | moderate | low | medium |
How Syncthing handles conflicts
When the same file is written simultaneously on two servers, Syncthing saves both versions: one keeps the original name, the other gets a .sync-conflict-<date>-<time> suffix. The winner is always chosen manually. In 90% of cases, conflict resolution takes less than 10 minutes. For production, we recommend staggered versioning: it stores copies for the last 30 days with pruning, giving 7–10 days to detect issues. For example, if two engineers modify an nginx config at the same time, Syncthing preserves both versions, and the on-call engineer manually picks the correct one.
Technical details: direct connection and discovery
In production, you don't want to depend on external Syncthing discovery servers. We configure direct connections with explicit addresses. This improves reliability and removes a single point of failure. According to the official Syncthing guide, the global discovery server should be disabled in production environments.
Step-by-step direct connection setup
- Get the Device ID on each server:
syncthing --device-id - On server-1, edit
config.xml: add the device with addresstcp://<server-2-ip>:22000 - Repeat on server-2 with server-1's address
- Enable monitoring via the REST API (key in
config.xml) - Check connectivity in the GUI or via the API
Installation and configuration
On both servers:
curl -s https://syncthing.net/release-key.gpg | gpg --dearmor -o /usr/share/keyrings/syncthing-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" > /etc/apt/sources.list.d/syncthing.list
apt update && apt install syncthing
# Run as a system user, not root
useradd -r -s /bin/false syncthing
systemctl enable --now syncthing@syncthing
By default, the GUI listens on 127.0.0.1:8384. For remote access, edit /var/lib/syncthing/.config/syncthing/config.xml:
<gui enabled="true" tls="false">
<address>0.0.0.0:8384</address>
<user>admin</user>
<password>...</password>
</gui>Or set up an SSH tunnel to the GUI — more secure. Configuring a sync folder Via the GUI or directly in config.xml:
<folder id="app-configs" label="App Configs" path="/etc/myapp/configs" type="sendreceive">
<device id="AAAAAAA-..." introducedBy=""></device>
<device id="BBBBBBB-..." introducedBy=""></device>
<rescanIntervalS>3600</rescanIntervalS>
<fsWatcherEnabled>true</fsWatcherEnabled>
<fsWatcherDelayS>10</fsWatcherDelayS>
<minDiskFree unit="%">5</minDiskFree>
<versioning>
<type>staggered</type>
<param key="maxAge" val="2592000"/>
<param key="cleanInterval" val="3600"/>
<param key="versionsPath" val="/var/backups/syncthing-versions"/>
</versioning>
</folder>fsWatcherEnabled=true enables inotify monitoring instead of periodic scanning. rescanIntervalS=3600 triggers a full scan every hour as a fallback. Staggered versioning stores old file versions with pruning: all versions from the last day, then daily, then weekly. Protects against accidental deletion or corruption.
| Parameter | Value | Description |
|---|---|---|
| type | sendreceive | Two-way synchronisation |
| rescanIntervalS | 3600 | Full scan every hour (fallback) |
| fsWatcherEnabled | true | inotify monitoring |
| minDiskFree | 5% | Pause if disk space low |
Monitoring Syncthing
Syncthing's REST API gives you everything you need for DevOps sync monitoring. Key metrics are available at /rest/db/status:
# Folder status and connections
curl -s -H "X-API-Key: your-api-key" http://localhost:8384/rest/db/status?folder=app-configs | jq .
curl -s -H "X-API-Key: your-api-key" http://localhost:8384/rest/system/connections | jq '.connections | to_entries[] | {device: .key, connected: .value.connected}'The API key is in config.xml under the <apikey> element. For Prometheus, set up syncthing_exporter or write a simple script that calls /rest/db/status and exposes metrics. Key indicators are needFiles and needBytes: if they don't drop to zero, synchronisation is stuck.
Quick diagnostic tip
If sync doesn't start, check that port 22000 is open in the firewall and that the config file has no syntax errors. Run `syncthing -generate=/var/lib/syncthing/.config/syncthing` to verify.What's included in our turnkey Syncthing setup
- Analysis of your current sync schema and server architecture
- Installation and configuration of Syncthing on all nodes
- Direct connection setup (no discovery servers)
- Creation of sync folders with versioning
- Monitoring setup via Prometheus/Grafana
- Schema documentation and runbook for on-call engineers
- Team training: how to resolve conflicts, add new servers
Timeline and experience
Basic setup between two servers — 2–4 hours. With versioning, monitoring and documentation — up to one day. For 10 servers, the timeline extends to 1–2 days. Pricing is determined individually after an infrastructure audit. Our team of certified DevOps engineers has configured Syncthing for more than 30 projects — from small startups to fintech companies with hundreds of servers. Syncthing is free software (MPL 2.0 license), no license purchase required. Savings compared to commercial solutions like Resilio Sync are 100% (€0 license cost vs €500+ per server). For a 10-server setup, replacing rsync cron jobs saves approximately $2,000 per month in engineering time. We guarantee reliable synchronisation with no file loss. Contact us for an infrastructure audit and receive a commercial proposal within 1–2 days.







