R2sync – a program to synchronize remote directories

R2sync is a program to synchronize two directories (or two files) in an efficient way. The directories can be local or remote. It synchronizes in two directions: files changed in the first directory will be copied to the second and files changed in the second directory will be copied to the first. If a file changed on both sides, r2sync will ask what to do, or skip the file.

The efficiency comes from two features:

  1. R2sync logs the sizes and modification times of files so that, when it is called again to synchronize the same directories, it can skip files that haven't changed.
  2. R2sync uses the rsync algorithm to avoid copying segments of files that are already the same. (This is useful if one or both directories are remote, because it avoids sending data over the network, at the cost of extra computations.)

To access a directory on a remote machine, r2sync either uses ssh to login to the machine and start an instance of r2sync there, or it connects to an already running r2sync on that machine. In the former case, the user starting r2sync must be able to login to the remote machine with ssh. In the latter case, the connection will not be encrypted.

R2sync is a command-line program. It can be invoked with two arguments:

r2sync directory1 directory2

If one of the directories is on a remote machine, this might look like:

r2sync photos my.example.com:misc/photos

By default, r2sync runs in interactive mode: It shows all pairs of files that need to be synchronised and asks what to do for each pair. You can accept the default action or choose a different one.

There are options to exclude certain files from being synchronised, to run in batch mode, to set the default action if files have changed on both sides and more. (See the manual.)

If you call r2sync often with the same options and arguments, it may be easier to store those options and arguments in a small file called a ‘profile’ and call r2sync with just a single argument:

r2sync profile-name


R2sync is inspired by unison. I decided to write r2sync, in early 2018, because using unison became unmanageable: Different versions of unison, or unison versions compiled with different compilers, cannot talk to each other. I have many different operating systems and I couldn't install enough versions of unison on each computer to give each pair of computers a compatible version.

The goal for r2sync therefore is to stay backwards compatible with earlier versions of itself. To that end the protocol that r2sync uses to talk to remote instances of itself is text-based, is documented and starts with the exchange of a version number. (For now, of course, there is only one version…)

The name ‘r2sync’ can be seen as a variant on ‘rsync’, because it uses the rsync algorithm, with a ‘2’ to indicate that it synchronises in two directions; or it can stand for ‘remote 2-way synchronise’.

I've been using r2sync since 2018, making small improvements every once in a while (in the portability, in the user interface, in the manual, etc.) It's time to make it public and see if other people have ideas to improve it further.


Version 0.1 has been tested on Sailfish 3, MacOS 10.14 (Mojave), Debian 4 (Etch), Debian 6 (Squeeze) and Debian 10 (Buster). Version 0.3 on Sailfish 3, MacOS 10.15 (Catalina), MacOS 11.1 (Big Sur), Debian 6 (Squeeze), Debian 10 (Buster) and Debian 11 (Bullseye).

R2sync is written in C and should compile on other POSIX-compliant platforms.

The program is Open Source.

Bert Bos
Created 2 November 2019, updated 6 January 2021