A feature you may not know about recent versions of rsync is that you can display an overall progress of the transfer. And by “recent” I mean since version 3.1.0, released in September 2013. To use it, you want to add these options instead of -v and/or --progress:

rsync --info=progress2 --human-readable --no-inc-recursive

For example:

> rsync --info=progress2 --human-readable --no-inc-recursive -a /Applications /tmp
          9.53G  21%  317.26MB/s    0:00:28 (xfr#83063, to-chk=443926/538653)

Update 2024-03-15: See this post for a screen cast demo of this progress.

One niggle here is that macOS ships with an old version of rsync. On macOS Sonoma 14.2.1, I have version 2.6.9:

> rsync --version
rsync  version 2.6.9  protocol version 29

So you’ll need to install a newer version of rsync. I use Homebrew:

brew install rsync

And now I have version 3.2.7:

> rsync --version
rsync  version 3.2.7  protocol version 31

I found out about this feature from this Server Fault question. --info=progress2 is the main new option to display an overall progress. From the rsync(1) man page:

There is also a --info=progress2 option that outputs statistics based on the whole transfer, rather than individual files. Use this flag without outputting a filename (e.g. avoid -v or specify --info=name0) if you want to see how the transfer is doing without scrolling the screen with a lot of names. (You don’t need to specify the --progress option in order to use --info=progress2.)

And also from --info=help:

> rsync --info=help
PROGRESS   Mention 1) per-file progress or 2) total transfer progress

The --human-readable option formats bytes nicely, like the 9.53G above.

The --no-inc-recursive (or --no-i-r) option provides a more accurate progress, as it does an initial file scan up front. From the man page:

Disables the new incremental recursion algorithm of the --recursive option. This makes rsync scan the full file list before it begins to transfer files. See --inc-recursive for more info.

While this can be beneficial, it may be slow for lots of files or over a network, so you may not want to use this one all the time. From one of the Server Fault answers:

This will build the entire file list at the beginning, rather than incrementally discovering more files as the transfer goes on. Since it will know all files before starting, it will give a better report of the overall progress. This applies to the number of files - it does not report any progress based on file sizes

This involves a trade-off. Building the entire file list ahead of time is more memory-costly and it can significantly delay the start of the actual transfer. As you would expect, the more files there are, the longer the delay will be and the more memory it will require.

I’ve found this pretty useful and fast enough most of the time, so I typically use it.