UN

Unison

Bidirectional file synchronizer with conflict detection

File Sync & Storage ★ 5.5k stars Medium setup GPL-3.0

Unison is a mature bidirectional file synchronization tool that reconciles changes made independently on two replicas. It detects conflicts, preserves both versions, and works over SSH for secure remote syncing.

Key features

  • True bidirectional sync
  • Conflict detection
  • Works over SSH
  • Cross-platform replicas

Pros & cons

Strengths

  • Very reliable
  • Fine-grained control

Trade-offs

  • Dated GTK interface
  • Version matching between hosts

Unison replaces

Last reviewed Sep 13, 2026 · 850 words

I keep a laptop and a desktop in step with Unison, over SSH, with no service running on either side, and it has not lost a file in a decade. That is the pitch. Unison (5,500 stars, GPL-3.0, written in OCaml, first released 1999) is a true bidirectional synchroniser: it looks at both replicas, works out what changed on each since the last run, propagates the changes, and stops and asks when the same file changed on both. It uses 64 MB of RAM and needs nothing installed beyond the binary on each host. The one historic trap, mismatched versions refusing to talk, has been mostly fixed, and this guide covers exactly where "mostly" ends.

The version rule that used to ruin everything

For most of Unison's life, both ends had to run the same version, and often the same OCaml compiler version too, or the connection failed with an archive-format error. Distros ship different versions, so a Debian desktop and a Fedora laptop frequently could not sync at all. Since the 2.52 release the wire format is stable across versions: any two 2.52-or-later builds interoperate. If either machine is on an older packaged release, download the static binary from the GitHub releases page rather than fighting the package manager. Check with unison -version on both hosts before doing anything else.

A profile makes it a one-word command

Unison reads profiles from ~/.unison/. This one syncs a project tree with a remote box over SSH, ignores build artefacts, and runs without prompting:

# ~/.unison/work.prf
root = /home/aidan/work
root = ssh://nas.local//tank/aidan/work

ignore = Name node_modules
ignore = Name .cache
ignore = Name *.o

batch = true
auto = true
prefer = newer
times = true
perms = 0o1777

Then unison work from a terminal does the whole run. batch suppresses prompts for non-conflicting changes, auto accepts the default action, prefer = newer resolves genuine conflicts by timestamp instead of stopping, and times keeps modification times identical on both sides so nothing looks changed when it is not. Drop prefer if you would rather be asked; the interactive resolver shows both versions and lets you pick per file. The double slash in the SSH root is not a typo; it means an absolute path on the remote.

Continuous sync exists but is not the point

unison -repeat watch work uses the unison-fsmonitor helper to resync on every change, which turns Unison into something like a two-machine Syncthing. It works, but if that is what you want, Syncthing is the safer choice: it is the bigger project in file sync, handles more than 2 devices, runs as a service, and versioning and conflict copies are built in. Unison's strength is the opposite pattern: a deliberate, auditable sync you run when you mean to, with a dry-run (-testserver for the connection, plain interactive mode for the plan) that shows every action before it happens. Cron it hourly if you want it unattended; the fine-grained profile control is what people stay for.

Conflicts, deletions, and the archive files

Unison stores a per-pair archive in ~/.unison/ recording what each file looked like at the last sync. That archive is how it distinguishes "deleted on A" from "never existed on B", so deleting the archive does not lose data but does trigger a full reconciliation on the next run, where everything looks new on both sides and a file removed on one end reappears from the other. Keep the archives; back them up with the rest of your home directory.

A conflict, where both replicas changed the same file, is never merged silently. With prefer set it picks; without it, the file is skipped and reported. Unison will not write a "conflicted copy" file the way cloud clients do, so a batch run with no prefer can leave one file out of sync indefinitely and only tell you in the log. Read the summary line at the end of each run.

Where Unison is the wrong tool

It is two replicas, full stop; three machines means two profiles and a hub. There is no phone client. The GTK interface is functional and looks like 2005. And it is a synchroniser, not a backup: a mistaken deletion propagates. For one-way copies to object storage, rclone is the better fit; for versioned backups, use a real backup tool alongside it. The Nextcloud vs Syncthing piece covers the daemon-based options if you decide you want something that runs itself.

What I'd do

Two machines, one SSH key, one profile like the one above, both hosts on 2.52 or later from the release binaries. Run it by hand a few times to trust the plan it shows, then move it to a cron entry or a -repeat loop. For anything beyond two hosts, or anything a family member has to use, install Syncthing and keep Unison for the sysadmin's own working tree, where explicit, scriptable, SSH-only sync is exactly right.

Compare Unison

21 head-to-head comparisons.

Similar file sync & storage apps