If you have an internet connection over which you can over the course of a few hours transport ca 1/2000 of the 45 TB, rsync is your friend, it can do "half-offline" updates! Meaning that the internet connection is only used to exchange file names, properties and checksums, and then the necessary changes are written to a file which can be transported a different way:
From A,
#     Only update files that are newer on A than on B
#     |  archive mode: keep times, owners, permissions
#     |  |     Don't actually send data over network, but write to file "batch-updates.archive"
#     |  |     |                                        Go through subdirectories
#     |  |     |                                        |           Show progress
#     |  |     |                                        |           |          |----copy from here----| |----copy to here on B----|
rsync -u -a    --only-write-batch=AforB-updates.archive --recursive --progress "${path_to_Alocalfiles}" "B:${path_to_Blocalfiles}"
# If batch update file is large: compress strongly if necessary
# Lower levels than -15 are much faster than typical SSD write speed (try -4),
# so compression is a pure win-win situation here.
zstd -T0 -15 AforB-updates.archive
Get a beefy homing pigeon housed at B, have it driven to A, staple the NVMe containing AforB-updates.archive.zst to it, and have it return the NVMe to B. On B, in the meantime, you do the same as on A above to get the B->A updates:
rsync --update -a --only-write-batch=BforA-updates.archive --recursive --progress "${path_to_Blocalfiles}" "A:${path_to_Alocalfiles}"
zstd -T0 -15 BforA-updates.archive
Feed the pigeon.
After that's done, on B,
zstd -T0 --stdout -d AforB-updates.archive.zstd | rsync --read-batch=- -a "${path_to_Blocalfiles}"
Copy the BforA-updates.archive.zst to your NVMe, get the ole SSD catapult from the cellar, wrap the NVMe in three layers of towels, and fire it back from B to A, and finally zstd -T0 --stdout -d BforA-updates.archive.zstd | rsync --read-batch=- -a "${path_to_Alocalfiles}".
If your internet connection is too slow even for that, things get.. more manual:
Sounds like a job for rdiff! (It's basically rsync, but split into separate "make file signatures", "calculate the deltas", "patch with the deltas" steps)
It makes a list of checksums of the local files (say, on server A). You can then carry that list to server B (maybe even online, it's not going to be immense amounts of data). Take these signatures, find the different parts of files on B, and save these differences to your portable SSD. Back at A, you can then apply the changes.
So, it'd look something like this to me (untested, written from top of head, no warranties, but I hope it helps)!
Write signatures:
#!/usr/bin/zsh
## Signature tree storage script
## Goes through the current directory, writes a file signature for every file
## into an identically named file under $sigs,
## and creates an archive ~/signatures-(current datetime).squash in the home
## directory
sigs="/path/to/signatures"
# Let's assume we only sync regular files, not empty directories, nor sockets, nor symlinks, nor device nodes,…
for f in **/*(.) ; do
  # remove trailing path component, i.e. file name from $f and use that to
  # create directory under sigs prefix
  mkdir -p "${sigs}/${f:h}" 
  # write signature to file in prefix
  rdiff signature -- "${f}" "${sigs}/${f}"
done
# Assuming quite a few files are similar on a 1.4 TB thing, let's spend some
# time when archiving the signature prefix on minimizing the store needed for
# these.
# We use squashfs as archive format, as mksquashfs deduplicates, and allows us
# to compress on the fly – and also, because on the reading end, we can just
# mount the archive without unpacking it.
mksquashfs "${sigs}" "~/signatures-$(date -Is).squash" -comp zstd
on the receiving end, you'd do the inverse: mount the signatures….squash file, go through the tree, and rdiff delta -- ${signature_file} ${actual_file} deltas/${actual_file} to write deltas. Archive the whole $deltas directory, carry back home, and rdiff path -- ${actual_file} ${delta_file} updated/${actual_file}.
     
    
syncthingmaybe?