I’ve had some luck establishing the bottleneck using strace on both the sender side and receiver side. This will show if the sending rsync is waiting on local reads or remote writes and if the receiving rsync is waiting on network reads or local writes.
This helps find the specific resources to check.
This Lemmy community has a great set of intro Linux lessons to get you started:
https://programming.dev/c/linuxupskillchallenge
The scheduling command for a one-time future run is the “at” command.