Ahmad

How to migrate data from a UGREEN NAS to TrueNAS SCALE with rsync

Copying terabytes over SSH fails the moment the connection drops, and starts again from nothing. Running rsync inside tmux with resume enabled turns a fragile all-or-nothing transfer into one you can walk away from overnight.

beginner20 minupdated 2026-09-13migrationnasrsyncsshtmuxtruenasugosugreenDownload script.sh

Before you start

  • Shell access on the machine that will pull the data
  • rsync and tmux available on it
  • SSH access to the source machine
  • Enough free space on the destination

Your values

Fill these in and every command below updates to match. Nothing is sent anywhere.

Run this at your own risk. These steps worked on my hardware; yours may differ. Take a backup first, read each command before running it, and see the disclaimer.

Moving off a UGREEN NAS running UGOS to TrueNAS SCALE means copying everything across the network, and that copy can take a very long night.

Start a multi-terabyte rsync over SSH, close the laptop, and come back to a dead session and a half-copied dataset. The transfer was tied to the SSH connection, and the SSH connection did not survive the night.

Nothing here is specific to UGREEN or TrueNAS. The same two habits apply to any NAS-to-NAS move where both ends give you a shell - Synology, QNAP, unRAID, a plain Linux box.

The fix is two habits, and they cost about thirty seconds to adopt.

Run it inside a named tmux session

tmux keeps the shell alive on the remote machine independently of your connection. Detach, close the laptop, reconnect tomorrow, reattach.

Name the session. In three days you will not remember which anonymous session was the important one.

bash
tmux new -s nas-migration

If the session already exists, attach to it instead:

bash
tmux attach -t nas-migration

Detach with Ctrl+b then d. The transfer keeps running.

Start the transfer with resume enabled

bash
rsync -aHAX --partial --info=progress2 \
  admin@nas-old.example.lan:/volume1/Shared/ \
  /mnt/tank/Shared/

What each flag is doing, because these matter:

  • -a archive mode: recurse, and preserve permissions, times, symlinks and ownership
  • -H preserve hard links, which archive mode does not do
  • -A preserve ACLs, -X preserve extended attributes
  • --partial keep partly-transferred files so an interrupted run resumes instead of starting that file again
  • --info=progress2 one overall progress line rather than a line per file

Without --partial, an interruption part-way through a 90 GB file throws away all 90 GB of it.

The trailing slash on the source matters. src/ copies the contents of src into the destination; src copies the directory itself into the destination. Getting this wrong is how you end up with {{DEST_PATH}}/src/src.

Watch it, or do not

bash
tmux attach -t nas-migration
expected output
    1.61T  47%   112.43MB/s    4:32:11

Run it again when it finishes

Always run the same command a second time. The first pass took hours, and things changed while it ran. The second pass only moves the difference, so it finishes quickly, and it tells you the first pass really did complete.

bash
rsync -aHAX --partial --info=progress2 \
  admin@nas-old.example.lan:/volume1/Shared/ \
  /mnt/tank/Shared/

Check before you trust it

--dry-run with --itemize-changes lists what a third run would do. Ideally nothing.

bash
rsync -aHAXn --itemize-changes \
  admin@nas-old.example.lan:/volume1/Shared/ \
  /mnt/tank/Shared/ | head -50

Any line beginning >f is a file it still wants to send. An empty result means the two sides agree.

Only now consider --delete

--delete removes files at the destination that no longer exist at the source. It is the right flag for keeping a mirror in step, and the wrong flag to have typed while the source was half-mounted.

Never use it on the first pass. Never use it without having run the --dry-run above and read the output.

bash
Destructive command. Read it before running it. This can delete data or interrupt service.
rsync -aHAX --delete --info=progress2 \
  admin@nas-old.example.lan:/volume1/Shared/ \
  /mnt/tank/Shared/

Leave the session behind

bash
tmux kill-session -t nas-migration