Using Syncthing as a Robocopy replacement for one-shot software distribution / mirroring

Hi all,

I’m working on an integration where I want to use Syncthing as a replacement for Robocopy for distributing files from one PC to multiple target PCs. I’m using Syncthing for its benefits of p2p, file block level deltas, etc. I do understand Syncthing is created for continous synchronization, but I believe it could fit my usecase of one-shot deployment / mirroring.

Requirements

I currently have a workflow where one machine acts as the source of truth for a software package, and a number of other machines receive that package.

For example:

  • PC1 = source machine

  • PC2, PC3 = target machines

The requirement is:

  • PC1 is the absolute source of truth

  • PC2 / PC3 should only receive

  • at the end of a distribution run, PC2 / PC3 should be exact mirrors of PC1, so there should not be any extra files on PC2/PC3 when synchronization is done

  • ideally, after the distribution run is complete, the syncing folder should be paused (this replaces an old Robocopy run-once flow, not a continuous synchronization model)

Current implementation

I have a backend application which runs on each PC on the network which stars Syncthing, adds the according list of remote devices to each PC, and the list of folders (which have the devices linked), and starts synchronization.

Issue #1

Synchronizing does not always end with exact mirrored folders

Suppose we distribute from PC1 (Send Only) → PC2, PC3 (Receive Only), given the target folders on PC2, PC3 are not empty.

The expected result is:

  • all files from PC1 end up on PC2 and PC3

  • any extra files that exist only on PC2 / PC3 should be removed

  • final folder contents should be identical

What I observe when syncing is done:

  • PC1 can show all the folders as Up to Date including PC2

  • but PC2 may still contain extra local files that do not exist on PC1, and those extra files are only visible if we inspect Syncthing Web interface on PC2 itself where we get the “Revert Local Changes” button

So effectively:

  • the target device is not a perfect mirror yet

  • someone would need to remote into PC2 and click Revert Local Changes manually

That is the behavior we want to avoid.

Two possible implementation approaches we are considering

Option 1: Keep PC1 = Send Only, PC2/PC3 = Receive Only, and auto-revert on the targets

This is the folder type model that seems safest for strict source-of-truth behavior.

  • PC1 = Send Only

  • PC2 / PC3 = Receive Only

At the end of a distribution run, the managing application would:

  1. poll Syncthing folder status on PC2 / PC3 using:

    GET /rest/db/status?folder=FOLDER_ID
    

    until the folder returns: state == "idle" AND needBytes == 0 AND needFiles == 0 AND needTotalItems == 0 AND pullErrors == 0

  2. detect whether the receive-only folder has local changes / “needs revert”

  3. automatically call the same operation as pressing Revert Local Changes, via:

    POST /rest/db/revert?folder=<folderId>
    

    on the target device itself

Is this the intended / recommended way to achieve strict mirroring with Syncthing? Is there a better signal to poll than just “folder is idle / up to date”?

Is there a cleaner way to know that the target is both: done receiving from PC1, and free of local drift?


Option 2: PC1 = Send Only, PC2/PC3 = Send & Receive, then clean up from PC1 at the end

The second idea we considered is, using folder types :

  • PC1 = Send Only

  • PC2 / PC3 = Send & Receive

The reason for considering this is that local differences on PC2 / PC3 would become visible from the PC1 side more easily, and the cleanup could potentially be triggered centrally from the source side using Override Changes on PC1.

The downside to this is that if PC2 contains extra files, those extra files may get announced to the cluster and PC3 may receive them as well temporarily, until local changes would be cleared from PC1 with “Override Changes”

That makes this approach feel risky for a deployment / mirroring use case, because we explicitly do not want target-local files to propagate.


Issue #2

We do not want continuous synchronization after deployment

This use case replaces a Robocopy one-shot distribution workflow.

That means once the distribution is complete, we do not necessarily want Syncthing to continue rescanning and synchronizing indefinitely. So we would pool again the folder status and then perform some actions. I’m considering one of these options for actions after a successful distribution run:

  1. Pause the folder on the devices

  2. Pause the devices / connections

  3. Leave Syncthing running but disable periodic scanning / only rescan on demand

Let me know if you have any advice and how should I shape my implementation.