A few weeks back I needed to migrate an entire ZFS pool from one machine to another. I used raw send to keep the stream compressed, and I used mbuffer to smooth out the send/receive (see the reference link at the bottom)

First, prepare the receiving end by creating the pool. If this is not a bootable pool, just create it the simple way:

zpool create ${poolname:?} ${disk:?}

Now start up mbuffer to receive the initial send stream ("-s" is for resumable receive in case the receive gets interrupted part way through)
I'm using a block size of 128k, a buffer size of 1G and listening on port 9090:

mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}

Now switch over to the sending machine. Here we will take a snapshot, and then send it over mbuffer to the receving machine. We'll do a raw and resumable send.

zfs snapshot -r ${poolname:?}@${snapname:?}
zfs send -Rvw ${poolname:?}@${snapname:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090

If the sending side has changed since the first snapshot completed sending, do an incremental send/receive to sync up the last changes (repeat as needed)

On receving machine, rerun the receiving command:

mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}

On the sending machine, take another snapshot and send over the incremental stream:

zfs snapshot -r ${poolname:?}@${snap2:?}
zfs send -Rvw ${poolname:?}@${snapname:?} ${poolname:?}@${snap2:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090


Using mbuffer to speed up slow zfs send | zfs receive - EveryCity
zfs send | zfs receive stalls the sender, resulting in a bursty and slow transfer process. The solution is to deploy mbuffer into the mix. MBuffer