Relayium

Bring your own node: use Relayium relay & storage for free

Last updated: 2026-08-06

Cross-network transfers and stored links use relay bandwidth and disk that cost us money, so they run on a free allowance and are paid past it. There's a way around that: run your own relay/storage node, bind it to your account, and your transfers flow through your node instead of ours — nothing metered, nothing billed.

This is different from self-hosting the whole Relayium server. You keep using your normal relayium.com account and the same apps; you're just adding a node you own to carry your traffic. This guide takes you from a fresh Linux box to an online node in about five minutes.

Why run your own node

Two reasons. First, cost: a node you own carries your relay and storage traffic directly, so it never touches our metered infrastructure and there is nothing to bill — your usage is free no matter how large.

Second, control: the relayed bytes and stored blobs live on hardware you run, under your own operational control. Realtime transfers stay end-to-end encrypted the whole way, so even your own node only ever sees ciphertext.

Install the node and bring it online

What you need before step 1

  • A Linux server reachable from the internet — a cheap VPS or an always-on box at home both work. Both amd64 and arm64 are supported.
  • root on that server, or sudo. The install needs it once; the node itself never runs as root.
  • The ability to open inbound ports — in the host firewall, and on a cloud VPS in the provider's security group too.
  • A relayium.com account you are signed in to. The install command is minted on your account page and carries a one-time token.
  • Disk, only if you want the node to store as well as relay. A relay-only node needs none — leave RELAYIUM_NODE_STORAGE_DIR out.

Four things happen in order: you mint the command, you run it, you open the ports, and you confirm the node came online. About five minutes on a fresh box.

  1. Sign in at relayium.com and open your account page at /me.

  2. Scroll to My Nodes and click Add node. Copy the install command right away — the token in it is shown once and cannot be shown again.

  3. Paste it on your server. It downloads the relayium-node binary, checksum-verifies it, installs it to /usr/local/bin, writes a systemd service and starts it.

    curl -fsSL https://relayium.com/install-node.sh | sudo RELAYIUM_CENTRAL_URL=https://relayium.com RELAYIUM_NODE_TOKEN=<your-token> RELAYIUM_NODE_STORAGE_DIR=/var/lib/relayium-node/blobs sh
  4. Confirm the service is up and will come back after a reboot. Both answers matter: active says it is running now, enabled is what survives a restart.

    systemctl is-active relayium-node
    systemctl is-enabled relayium-node
  5. Open the inbound ports on the host firewall. Being Online needs only outbound access, but peers relay and store over these.

    sudo ufw allow 3478/udp        # TURN
    sudo ufw allow 8081/tcp        # storage
    sudo ufw allow 49152:65535/udp # relay
  6. On a cloud VPS, allow the same ports in the provider's security group as well. ufw alone leaves them blocked upstream, and the node looks healthy the whole time.

  7. Back on /me, watch the node flip to Online — usually within about 30 seconds. From then on your account's transfers prefer it automatically.

  8. Optional: turn on "Only use my own nodes for relay/storage" so a transfer fails rather than quietly falling back to our shared infrastructure.

What a working node looks like

systemd reports the service both active and enabled, and the node shows Online under My Nodes. active on its own is not enough — a node that is not enabled disappears at the next reboot.

$ systemctl is-active relayium-node
active
$ systemctl is-enabled relayium-node
enabled

Is it safe to run this installer as root?

Before anything else: BYO nodes run the same code and the same hardening as our own fleet nodes — the same binary from the same signed release, installed by the same script, under the same systemd unit. The only difference is whose machine it is. Everything below describes both.

It is a fair question about a command that pipes a script off the internet into a root shell, and it deserves a specific answer rather than a reassurance. Root is used for the install and for nothing the node does afterwards. The installer creates a system account called relayium-node with no login shell and no home directory, writes the systemd units, starts the service, and exits. The node itself never runs as root: its unit sets User=relayium-node, so from the moment it comes online it is an unprivileged account that owns nothing else on your machine. (Auto-update, which is on by default, does add a second unit that runs as root — the next section is entirely about what that one can and cannot do.)

Around that account the unit puts a systemd sandbox. Every line is aimed at something an attacker would reach for if they ever took over the node process. Nothing here is hidden from you: after installing, read the whole unit with cat /etc/systemd/system/relayium-node.service.

In the unitWhat it blocks if the node is ever compromised
User=relayium-nodeThe attacker is a user who owns nothing, not root.
ProtectHome=yes/home and /root are invisible — no SSH private keys, no other projects' data.
ProtectSystem=strictThe whole filesystem is read-only; no system file can be modified.
ReadWritePaths=The only writable places are the node's own state directory and, if you configured one, the storage directory. Writes anywhere else fail.
NoExecPaths=Nothing in the storage directory can be executed — an uploaded file cannot be run.
NoNewPrivileges=yesNo route back up to root; the usual escalation tricks are closed off.
CapabilityBoundingSet=Empty — no Linux capabilities at all.
ProtectKernelTunables=yes, ProtectKernelModules=yesThe kernel is out of reach: no sysctl changes, no module loading, no rootkit.

What the auto-updater can and cannot do

The installer also sets up a self-update timer, on by default: relayium-node-update.timer asks relayium.com roughly every ten minutes what version this node should be running. That is a second unit, and it runs as root, so it owes you its own account of itself.

Central never sends a binary. Its entire answer is a version number, two flags (may this node move now, and is this a deliberate downgrade) and a short reason string — no bytes, no URL, no command. The node then fetches that release itself, checks the archive's SHA-256 against the release's checksums.txt, and verifies an ECDSA P-256 signature over checksums.txt using a public key compiled into the very binary doing the checking. The private half of that key is not on the server answering those polls. So a compromised central could name a version; it could not mint a binary that passes.

The updater and the node are two separate processes with opposite powers. relayium-node.service is the sandbox above — under ProtectSystem=strict it cannot write to /usr/local/bin at all, so the node can never modify a binary, its own included. relayium-node-update.service is a small oneshot unit that runs as root and deliberately carries no sandbox, because replacing a file in /usr/local/bin needs exactly the privilege the node's sandbox exists to deny it. Keeping that power in one single-purpose unit, instead of loosening the node's own hardening, is the whole point of the split: the process with root only ever swaps binaries, and the process in the cage can never touch one.

An update that goes wrong undoes itself. The updater keeps the previous binary beside the new one, restarts the service, then watches for a heartbeat for up to ten minutes; if the new version does not report healthy in that window it puts the old binary back, restarts again, and records the bad version so it is not retried. Stored files are never read, moved or deleted by any of this.

Removing your node

Uninstalling is one script, and it is the same one whether your node stores files or only relays. It removes the units, the binary, the config and the service account, and makes a best-effort call telling relayium.com the node is gone. If that call fails it is one line on your terminal, not a broken uninstall — it prints the node's ID so it can be marked removed by hand.

Download it, check it, then run it. Piping straight into sh means a 404 or a network blip makes the whole command print nothing and exit 0, which reads exactly like a successful uninstall.

It removes only what it recognises: anything unexpected in the state or storage directories is kept and reported rather than swept away.

curl -fsSL https://relayium.com/uninstall-node.sh -o uninstall-node.sh && \
  [ -s uninstall-node.sh ] && sudo sh uninstall-node.sh

When it doesn't work

Five failures cover nearly every node that does not come up, and three of them look healthy from the server: the service is running, and only the account page or a listening socket says otherwise.

Symptom, check, fix

The shell answers "relayium-node: command not found".
command -v relayium-node
# nothing printed

The binary is not installed. You never install relayium-node separately — the one-line command from the account page is what downloads it, puts it on your PATH and starts it as a service. Run that command instead.

The service is active, but the node never turns Online on the account page.
journalctl -u relayium-node -n 50 --no-pager

Online is decided by an outbound heartbeat, so a firewall is rarely the cause here — registration is. The token is one-time, so a command that was already run, or an old one from a previous attempt, fails. Click Add node again for a fresh command and re-run it.

The node shows Online, but transfers still run over our shared infrastructure.
sudo ss -lunp | grep 3478

Online proves only the outbound heartbeat. Peers need the inbound ports: confirm the node is listening, then open 3478/udp, 8081/tcp and 49152-65535/udp in the host firewall and in the cloud security group. To rule out a silent fallback entirely, turn on the only-my-own-nodes setting.

The uninstall printed nothing, exited 0, and the service is still there.
systemctl status relayium-node
# active (running)

That is exactly what piping a failed download into sh looks like: a 404 or a network blip prints nothing and exits 0, which reads like success. Download the script, check it is not empty, then run it — that is why the command in this guide is written in three parts rather than one pipe.

The uninstall refuses while the storage directory still holds files.
sudo ls /var/lib/relayium-node/blobs | wc -l

Deliberate. Every stored file lives on exactly one node and there are no replicas, so removing the node makes those files unreachable. Wait for the count to reach zero as blobs expire, or accept the loss with RELAYIUM_NODE_FORCE=1. Environment variables do not survive a pipe into sudo sh, so pass them as sudo env RELAYIUM_NODE_FORCE=1 sh uninstall-node.sh.

Frequently asked questions

I got "relayium-node: command not found" — what went wrong?

You ran the relayium-node binary before installing it. Use the one-line install command from the account page (the curl … | sudo … sh form): it downloads the binary, puts it on your PATH, and starts it as a service. You never install relayium-node separately.

Does the node stay online after a reboot?

Yes. The installer registers a systemd service that is enabled on boot and set to Restart=always, so it comes back after a reboot and restarts itself if it crashes. Nothing extra to run.

How is this different from self-hosting Relayium?

Bring-your-own-node keeps your normal relayium.com account and apps and just adds a node you own to carry your traffic. Self-hosting runs the entire server stack (accounts, web app, signaling) on your own domain — see the "Self-host Relayium" guide for that.

Can anyone else use my node or see my data?

No. A node is bound to your account by its token and only carries your account's traffic. Realtime transfers are end-to-end encrypted and stored blobs are ciphertext your node can't read. Your data and node configuration are only ever usable by you.

Sign in, open your account page, and add your first node in under a minute.

Open the account page

Keep reading