Relayium

Keep an off-host copy on your own server over SSH with the Relayium CLI

Last updated: 2026-09-01

If you already have SSH access to a box — a VPS, a home server, a NAS, a workstation — you can put a copy of your files on it with the Relayium CLI without setting up a sync service or an account. The transfer runs over your existing SSH connection, so the bytes go straight to your server and never pass through Relayium.

Be clear about what this gives you: an off-host copy of the files as they are right now. It is not a versioned backup. Nothing here keeps yesterday's version of a file you overwrote, and a scheduled mirror carries a deletion or a corrupted file at the source over to the copy on its next run. If you need to recover a file as it was last week, pair this with snapshots or a backup tool that keeps history.

This guide covers pushing and pulling directories, what the integrity check does and does not cover, why push refuses to run twice into the same destination, and how to keep the copy current on a schedule with cron.

Before you start

Everything below is the relayium CLI, so install it first if you haven't. On macOS or Linux, one command drops a prebuilt binary on your PATH:

curl -fsSL https://relayium.com/install.sh | sh
  • Prefer to pick the file yourself, or on Windows? Grab a binary from the releases page — relayium.com/cli lists every install option (or go build ./cmd/relayium if you have Go).
  • relayium --version confirms it's installed. Skip this and the commands below just print 'command not found'.

Push a directory to your server

What you need

  • SSH access you already use. ssh user@your-server true must return silently — push reuses that exact connection and configures nothing of its own.
  • A writable destination on the server. The parent of the destination path has to exist and be writable by that SSH user.
  • Optionally relayium on the server, which is what buys the up-front collision check and per-file SHA-256. Without it push still works, over a plain tar stream that verifies nothing.
  • No Relayium account and no daemon on either end. Nothing here talks to Relayium's servers.

push takes one or more sources and an scp-style destination. Relayium connects over SSH using your usual keys and config, then streams the files to the destination directory:

  1. Confirm the SSH access push will reuse. A silent return means your keys, host alias and port are already right.

    ssh user@your-server true
  2. Find out which protocol you will get. A path means the native protocol — an up-front collision check and per-file SHA-256; no output means the tar-stream fallback, which checks nothing per file.

    ssh user@your-server command -v relayium
  3. Push the directory. The destination is scp-style, and the trailing slash means "into this directory".

    relayium push ./photos user@your-server:backups/
  4. Override the key or the port for this one command if your ssh config doesn't already cover the host.

    relayium push -i ~/.ssh/id_ed25519 -p 2222 ./photos user@your-server:backups/
  5. Confirm what landed. push ./photos reproduces photos/ under the destination, so the folder name travels with it.

    ssh user@your-server ls backups/photos

What a successful run looks like

On the native protocol, push prints one line per completed file and exits 0. Against a bare server it prints a single summary line instead — that is the tar fallback, and it is also success.

relayium push ./photos user@your-server:backups/
  photos/IMG_0413.jpg (2314518 bytes)
  photos/IMG_0414.jpg (1998233 bytes)

# against a server with no relayium installed, one summary line instead:
sent 2 file(s) (zero-dependency mode)
  • It reuses your ~/.ssh/config, so host aliases, keys and ports you already set up just work.
  • If relayium is installed on the server, it uses the native protocol: the whole batch is checked for collisions before any bytes are sent, and each file it transfers is verified by SHA-256 and staged before it is installed.
  • If not, it falls back to piping a tar stream into the remote's own tar -x -k, so a bare server with no relayium still works — but that path verifies nothing per file and can leave a batch partly applied.

Pull files back

Restoring is the same command in reverse: give a remote source and a local destination directory. This is how you recover a backup, or sync a server's output down to your laptop:

relayium pull user@your-server:backups/ ./restore
  • Unlike push, pull always needs relayium already installed on the remote — it has no tar fallback, so install it there first if it's missing.

Integrity is built in — resume is not

With relayium on both ends, each file push transfers is verified end to end with a SHA-256 hash and staged before it is installed, so what lands on the server is byte-for-byte what you sent. That much is real, and it is the reason to install relayium on the destination.

What push does not do is resume. It is not a transaction either: files are installed one at a time as they pass, so a connection lost partway through leaves the files that already landed in place — and because those files now exist, re-running the same push is refused by the collision check rather than continuing. Push the missing paths explicitly, or use relayium sync, which is the mode that skips what already matches and does continue a partial file on a later run.

--no-resume is accepted by push and pull and does nothing there. It is real on a serve listener receiving a sync, which is where a partial file can exist in the first place.

  • The SHA-256 check runs automatically; a mismatch is reported and that file is flagged as failed.
  • It covers what the run transfers. The tar fallback hashes nothing, and sync's size+mtime skip means an unchanged-looking file is never read and so never hashed.
  • Neither push nor pull resumes, in either protocol. Use sync for a directory you expect to be interrupted.

Keep the copy current on a schedule with cron

Schedule sync, not push. push refuses a destination that already exists, so a nightly push into the same directory succeeds once and is refused every night after that. sync is the mode built for a repeated run: it skips files whose size and modification time are unchanged, sends only what changed, and continues a partial file left by an interrupted run.

It is a single non-interactive command that uses your SSH keys, so it drops straight into cron. Point it at a key with no passphrase (or an agent), and log the output so you can see failures:

# back up every night at 2am — add to your crontab (crontab -e)
0 2 * * * relayium sync -i ~/.ssh/backup_key ~/documents user@your-server:backups/ >> ~/relayium-backup.log 2>&1
  • A nightly sync that gets interrupted continues the next night: what already matches is skipped, and a partial file is carried on rather than restarted.
  • sync has no tar fallback, so relayium must be installed on the server. That is a loud failure rather than a silent downgrade.
  • The command exits non-zero if any file fails its integrity check, so cron's mail-on-failure catches problems.
  • This keeps the copy current; it keeps no history. Add --delete only if you want a deletion at the source to remove the file on the server too — which is a mirror, and the opposite of what you want if you might delete something by mistake.

When a scheduled copy doesn't land

A scheduled job fails quietly by nature — nobody is watching the terminal. These four are the ones that actually happen, and each is decided by a command you can run right now. They are not the only ways a run can fail: the destination can be out of space, or unwritable by that SSH user.

Symptom, check, fix

The cron job hangs, or the log ends at a password prompt.
ssh -i ~/.ssh/backup_key -o BatchMode=yes user@your-server true
# Permission denied (publickey).

BatchMode=yes refuses to prompt, which turns a silent hang into this line. Add that key's public half to the server's ~/.ssh/authorized_keys, or point the job at a key an agent already holds.

The crontab line runs but the log stays empty.
command -v relayium
# /usr/local/bin/relayium

cron runs with a minimal PATH that usually has no /usr/local/bin, so the line fails before relayium starts. Write the absolute path the check just printed into the crontab entry, and keep the >> ~/relayium-backup.log 2>&1 redirect so the next failure is visible.

The job reports success every night, but nothing was ever verified.
ssh user@your-server command -v relayium
# (prints nothing)

No relayium on the remote means push took the tar-stream fallback, which hashes nothing per file and can leave a batch partly applied when a name collides mid-extraction. Install the CLI on the server to get the up-front collision check and per-file SHA-256 back. It also lets you switch the job to relayium sync, which has no fallback at all and fails loudly instead of downgrading silently.

"N file(s) could not be verified or saved" and a non-zero exit.
relayium push ./photos user@your-server:backups/
# 1 file(s) could not be verified or saved: [photos/IMG_0413.jpg]
# exit status 1
echo $?
# 1

Either the SHA-256 computed on arrival did not match the one sent, or relayium on the server could not save or install the file — no free space, no permission, or a destination path it cannot write to; the message does not say which. The first line is printed by relayium on the server and forwarded over SSH, and exit status 1 is that remote process's exit code. Either way, the native protocol stages each file and installs it only after its hash matches and it has been saved — so this transfer did not install that path. That does not prove nothing is there, since something else may have created it in the meantime, so do not delete anything already at the destination just because of this message. If other files from that batch did land, re-running the whole batch is refused by the collision check, so push that one path on its own, to the same intended destination. If it fails again it is not a one-off transit error: check free space, permissions and the destination path on the server, and look at the source file (something writing to it while it is read).

Frequently asked questions

Do the files go through Relayium's servers?

No. push and pull run entirely over your own SSH connection. Relayium's servers are never involved and you need no account.

Does the server need relayium installed?

It depends on the direction. For push, it's optional: with relayium on the remote you get the native protocol — an up-front collision check and a per-file SHA-256 on everything it transfers — and without it, push falls back to a plain tar stream over SSH, which still works but verifies nothing per file. For pull, it's required: pull always needs relayium on the remote (it has no tar fallback), so install it there first. sync needs it too, for the same reason.

How does it choose which SSH key and port to use?

It reads your ~/.ssh/config like ssh does, so host aliases, keys and ports are picked up automatically. You can also override them per command with -i for the identity file and -p for the port.

Is this faster than rsync?

For pushing to your own server it's in the same ballpark as rsync over SSH; the point isn't to beat rsync but to give you one tool that also does cross-network and server-to-server transfers with the same per-file integrity check. On the history question the two are alike: neither rsync nor relayium sync keeps an earlier version of a file, so both are a copy rather than a backup.

Is this a backup?

It is an off-host copy, which is one part of a backup and not the whole of it. push writes the files as they are now, and a scheduled sync keeps that copy current — which also means it carries over a deletion or an in-place corruption at the source on its next run, and --delete makes the deletion half explicit. Nothing here retains an earlier version, so if you need to recover a file as it was last week, keep snapshots on the destination or use a tool that versions.

Put an off-host copy of your next directory on your own server — over your own SSH, integrity-checked, and free.

Get the CLI

Keep reading