← Blog

Sync STL files between a PC and a NAS reliably

Pick a direction and stick to it: a mount, a one-way rsync push, or Syncthing for two-way. Plus what changes when a library indexes the NAS folder in place.

nasguideself-hostedorganization

Most unreliable model sync is a one-way tool being asked to work in two directions. rsync from the PC is dependable right up until you edit a file on the NAS and the next push quietly restores the old version over it. So the first decision is not which tool, it is whether files change in one place or two.

If you design on the PC and the NAS is storage, push one way and never sync back. If you genuinely work from two machines, use a tool built for two directions and turn on its versioning. If you would rather not have two copies at all, mount the share and work on it directly. Those are the three setups that hold up; anything that mixes them is the setup that eats a file eventually.

Work directly on the mount when you can

The simplest reliable arrangement is no sync. Mount the share, point your slicer’s open dialog at it, and there is only ever one copy to be wrong about.

Terminal window
# NFS, in /etc/fstab
192.168.1.10:/volume1/3dprints /mnt/nas/3d nfs defaults,_netdev,soft 0 0
# SMB / CIFS, in /etc/fstab
//192.168.1.10/3dprints /mnt/nas/3d cifs credentials=/root/.nas-creds,uid=1000,gid=1000,iocharset=utf8,_netdev 0 0

_netdev keeps the system from trying the mount before the network exists, and soft on NFS means an unresponsive server gives you an I/O error rather than a process stuck in uninterruptible sleep. Keep credentials in a file with chmod 600 instead of on the fstab line, where every user on the box can read them.

What you give up is working offline and slicer responsiveness on large meshes, since every mesh load crosses the network. A 200 MB STEP assembly over Wi-Fi is a noticeably worse experience than the same file on local NVMe. If that bites, copy the handful of files you are actively working on to the PC and keep the archive on the mount.

Push one way with rsync

When the PC is where files change, one direction is all you need and the only thing to get right is not deleting the wrong side.

Terminal window
rsync -a --dry-run --delete-after ~/3d-models/ /mnt/nas/3d/

Run it with --dry-run first, read the delete list, then run it again without. The trailing slash on the source means “the contents of this directory”; leaving it off copies the directory itself into the destination and produces /mnt/nas/3d/3d-models/. That mistake then presents itself as a sync failure. --delete-after removes files on the NAS that no longer exist on the PC, which is what makes the copy a mirror and also what makes a wrong path destructive. If you are not sure, leave --delete-after out: an extra stale STL costs nothing next to a deleted folder.

-a preserves modification times, which matters more than it sounds. Timestamps are how both rsync and most indexers decide a file is unchanged, so a mirror with intact times skips almost everything on the second run instead of rehashing your whole library.

Two other flags earn their place. -n is the same thing as --dry-run when you want it short, and -c compares by checksum rather than size and time. It is slow, and running it once a quarter confirms that the two sides really do match. Bit rot and a truncated transfer look identical to a size-and-time comparison.

By default rsync writes each file to a temporary name and renames it into place when the transfer completes, so nothing else ever sees a half-written STL. --inplace turns that off and writes directly into the destination file. It saves space on huge files and it is the wrong choice here, because anything watching that folder can read a partial mesh.

For a Windows PC, robocopy with /MIR is the equivalent, with the same warning attached to the same feature.

Use Syncthing when both sides change

Two-way sync needs a tool that keeps state about what each side has seen, and Syncthing is the usual self-hosted answer: install it on the PC and on the NAS, share a folder between the two devices, and it reconciles continuously without a cloud account in the middle.

Turn on file versioning before you trust it with anything. Syncthing defaults to no versioning, which means a delete or an overwrite on one machine propagates to the other with no copy left behind. Staggered versioning is a reasonable choice, since it keeps more of the recent versions than the old ones. Checked August 19, 2026.

When both sides really do change the same file, Syncthing keeps both. The copy with the older timestamp is renamed to <name>.sync-conflict-<date>-<time>-<device>.<ext>. That is the behavior you want, because two files to compare beats one file silently chosen for you.

If you want the shape of a one-way push but with Syncthing running it, set the PC folder to Send Only and the NAS folder to Receive Only. The folder types do what their names say: a Send Only folder ignores incoming changes, and a Receive Only folder keeps local changes to itself rather than distributing them. Note what that implies further down, though, because a library writing new revisions into a Receive Only folder is making exactly the kind of local change that mode is designed to hold back.

Once PrintStash indexes the folder

None of the above involves PrintStash, and that is deliberate: the sync is a filesystem problem, and a library reads the result. Add the NAS folder as a shared volume and PrintStash indexes the files where they already live, storing only the parsed metadata and a generated thumbnail. The folder stays the source of truth, and your NAS snapshot policy keeps covering the actual bytes.

Four behaviors matter before you point it at a folder that a sync tool is also writing to.

Real-time watching does not work on network mounts. PrintStash uses filesystem events on local paths, and the kernel does not deliver those for NFS or SMB, so a shared volume on a network folder falls back to its scan schedule. Hourly is a sensible starting point. You can force watching, which polls with stat instead, and it costs more work than it saves for most libraries.

A scan reads size and modification time first and only rehashes when one of them moved, with two seconds of slack on the timestamp to absorb the rounding that FAT and SMB apply. An rsync mirror that preserves times therefore produces a nearly free scan. A sync tool that rewrites timestamps produces a full rehash every run.

An unmounted share does not delete your library. If the mount point is missing, unreadable, or empty while the volume still has indexed files, the scan aborts and marks itself errored instead of trashing everything. That specific accident is what the rule exists to prevent. Remount and scan again.

Write-back goes into the same folder. Uploading a file or adding a revision through the web UI to a model that belongs to a shared volume writes the new file into that folder rather than into PrintStash’s own storage, and it only ever adds files, never overwrites. With a Send and Receive folder, that new file appears on your PC on the next pass, usually what you want. With the NAS side set to Receive Only, it does not: Syncthing counts it as a local change, holds it back, and offers to revert it. Pick one or the other deliberately. If you would rather PrintStash never wrote into the folder at all, mount the path :ro in Docker and accept that uploads and revisions for models in that volume then fail.

The one gotcha to plan around

A scan walks every subdirectory and indexes anything with a supported extension, including directories whose names start with a dot. Syncthing’s versioned copies live in .stversions inside the shared folder by default, so turning on versioning and pointing a shared volume at the same folder gives you every old revision of every mesh as its own model in the library.

Two ways out. Move the versions directory outside the synced folder, which Syncthing supports as long as it stays on the same filesystem, or point the shared volume at a subfolder that holds only your models. The first is tidier if you already have the folder layout.

Conflict copies land in the library too, for the same reason: bracket.sync-conflict-20260819-101500-K7QX3RN.stl still ends in .stl. That one is arguably a feature, since a conflict you can see is better than a conflict you cannot, but knowing it in advance saves you diagnosing a duplicate as an indexing bug.

Partial transfers are not a problem in the same way. Syncthing’s temporary files are named .syncthing.<name>.tmp and rsync’s default temporary names end in a random suffix rather than a model extension, so neither gets indexed while it is still being written.

Questions that come up

Which method should I actually pick?

Mount the share if your models are large and your network is good, since one copy cannot disagree with itself. Push one way with rsync if you design on one PC and want the NAS as an archive, because it is the least surprising thing that can happen to your files. Use Syncthing only if you genuinely edit from two machines, and turn on versioning at the same time you turn on Syncthing. The unreliable setups are almost always an rsync mirror being used as if it were bidirectional.

Do I still need a backup if the NAS has my files and PrintStash indexes them?

Yes, and the reason is specific. PrintStash’s own backup archive covers its database, the files it owns, thumbnails, and a manifest. Files indexed from a shared volume are not PrintStash’s bytes, so they are not in that archive, and your NAS snapshot or offsite copy has to cover them. A sync is not a backup either: a two-way sync propagates a delete faithfully, which is exactly what you do not want after a bad afternoon. Backups that actually restore covers the boundary in detail.

How long after a file lands on the NAS does it appear in the library?

On a network mount, up to one scan interval, because real-time watching needs kernel filesystem events that NFS and SMB do not deliver. Pick a schedule you can live with, hit Scan now when you are impatient, and expect the first scan on a large folder to take a while since it hashes and parses everything. Later scans only touch files whose size or timestamp changed, so a mirror that preserves times stays cheap.

Will syncing the same folder from two PCs corrupt anything?

Not corrupt, but it can lose an edit if the tool is not built for it. Syncthing detects the case and keeps both copies, renaming the one with the older timestamp to include sync-conflict and the date. An rsync mirror has no concept of a conflict: whichever side you named as the source wins, and the other side’s newer file is overwritten without a word. If two machines really do edit the same models, that is the situation two-way sync exists for.

Should the sync folder and the PrintStash vault be the same place?

No, and PrintStash keeps them separate on purpose. The vault holds files PrintStash owns and copied, while a shared volume indexes files it does not own and never deletes. Mixing the two would mean a sync tool rewriting files that PrintStash considers its own, with hashes and metadata drifting from what is on disk. Keep your synced library as a shared volume and let uploads through the web UI write back into it.

Sources

  • Syncthing documentation on file versioning, folder types, and temporary and conflicting files for the defaults and the exact filenames. Checked August 19, 2026.
  • The rsync manual page for --inplace, --delete-after, -c, and the default temporary-file behavior.
  • PrintStash external library scanning at the shipped v0.11.4 release in the repository, for the extension filter, the two-second timestamp tolerance, and the empty-root abort.
  • PrintStash shared volumes guide for mounting a NAS path into the container and the watching modes.