SSD Nodes Learn 🎉 VPS from $4.99/mo
Guides Matt ConnorBy Matt Connor · Updated 2026-08-12

Run a Tor relay on your VPS

Set up a guard or middle Tor relay on a Linux VPS: torrc, bandwidth accounting that protects a metered plan, nyx monitoring, and the slow consensus ramp.

What a Tor relay on a VPS does

A Tor relay is a Tor daemon on a machine with a public IP address that forwards encrypted traffic for other people. The directory authorities publish it, and Tor clients build circuits through it. A guard or middle relay only ever hands traffic to another relay, so it never opens a connection to a website on a stranger's behalf. That single fact is why it attracts no abuse mail, and why it is the contribution that fits an ordinary VPS.

The work is small: one package, fifteen lines of config, one firewall rule, one restart. The rest of this guide is the part that goes wrong. Bandwidth arithmetic on a metered plan, and the reason a perfectly healthy new relay looks dead for a week.

Guard, middle, bridge or exit: pick before you install

One daemon runs all four roles. Your config, plus the directory authorities, decides which one you are.

  • Middle relay. It receives traffic from a guard and passes it to another relay. It never contacts a destination site. Every new relay starts here.
  • Guard relay. The same configuration, with a flag on top. The directory authorities give the Guard flag to relays that have been fast and stable for long enough. You do not choose it. You earn it, and the config below is what earns it.
  • Bridge. A relay that is deliberately kept out of the public directory and handed out privately to users in places where Tor is blocked. It is the smallest commitment of the four: low bandwidth, no public listing, and the right first step if your plan is tiny.
  • Exit relay. The last hop, which opens the connection to the destination site. Every request a user makes leaves from your IP address, so abuse reports and police inquiries arrive at whoever owns that address.

The exit is the one role that does not belong on a general-purpose VPS. Run an exit only on a provider that has agreed in advance to receive that mail, with its own IP address and a published abuse contact. Most standard hosting terms forbid it, and the usual result of ignoring that is a suspended server and a lost IP address. A guard or middle relay carries the same user traffic with none of that exposure.

Everything below builds a guard/middle relay. ExitRelay 0 is the line that keeps it one.

What the VPS needs before you start

The Tor Project publishes hard requirements for relays. As of August 2026 they are: one public IPv4 address for the relay, at least 10 Mbit/s of bandwidth in each direction with 16 Mbit/s recommended, at least 100 GB of outbound traffic per month, and 512 MB of RAM below 40 Mbit/s or 1 GB above it. There is no fixed uptime rule, but a relay that runs less than two hours a day is of little use to the network.

The 10 Mbit/s figure describes the line, not the setting. You need a port that can do it. How much of that line you allow the relay to use is a separate decision, made against the monthly transfer allowance. Read your plan before you touch the config. If you are still choosing a box, what a VPS actually costs per month covers how transfer allowances are sold, and measuring the real network throughput of a VPS shows how to find out what the line does with iperf3 instead of trusting the sales page.

Harden the machine first. A relay is a public service on a public address, and the address gets scanned within minutes of being published. Locking SSH down to keys and a hardened sshd config takes ten minutes and belongs before the relay goes live, not after.

Install tor from the Tor Project repository

Use the Tor Project's own apt repository rather than the distribution package. Relay code moves faster than a stable release does, so fixes reach this repository first and the distribution package lags behind between releases.

sudo apt update
sudo apt install -y apt-transport-https gnupg wget

Add the signing key, then the repository. The codename is read from the machine, so the same block works on Ubuntu 24.04 (noble) and Debian 13 (trixie).

wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc \
  | gpg --dearmor \
  | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/null

CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")
echo "$CODENAME"

sudo tee /etc/apt/sources.list.d/tor.sources >/dev/null <<EOF
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: $CODENAME
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpg
EOF

sudo apt update
sudo apt install -y tor deb.torproject.org-keyring
tor --version

tor --version prints the version you just installed. If apt update printed a NO_PUBKEY error instead, the dearmored key is not at the path named in the Signed-By: line, so apt has no key to check the release file with. The deb.torproject.org-keyring package matters for later: it ships the signing key as an ordinary package, so apt keeps working when that key is rotated.

Turn on automatic upgrades, then teach them about the new origin.

sudo apt install -y unattended-upgrades apt-listchanges

On Ubuntu, add the Tor origin to the Allowed-Origins block in /etc/apt/apt.conf.d/50unattended-upgrades:

Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
        "TorProject:${distro_codename}";
};

On Debian the same file uses Origins-Pattern, where the line to add is "origin=TorProject";. Check the result with sudo unattended-upgrade --debug --dry-run, which prints the origins it will act on and writes nothing.

The torrc that matters

The package installs a long, heavily commented /etc/tor/torrc. Only a handful of lines matter for a relay. Add them at the end of the file.

Nickname mynicerelay
ContactInfo relay-ops[at]example.com
ORPort 9001
ExitRelay 0
SocksPort 0

Nickname is 1 to 19 characters, letters and digits only. It is not unique across the network and it is not your identity, the fingerprint is. It is how you will find your own relay in a search box, so pick something you can spell over the phone.

ContactInfo is published inside the relay descriptor, which is a public document that anyone can download, so the address will be scraped. Use an address you will still read in two years, and obfuscate it if you like. This is the only channel the Tor Project has to warn you about a problem with your relay.

ORPort 9001 is the port other relays and clients connect to. 9001 is conventional. Port 443 is the other common choice, because some restrictive networks allow only outbound 443, so a relay listening there is reachable to more clients. Pick 443 only if nothing else on the box needs it.

SocksPort 0 switches off the local SOCKS proxy, which a relay does not use, and removes one listening socket from the machine. ExitRelay 0 writes the intent into the file: this relay will never connect to a destination on a user's behalf, and nobody reading the config later has to work that out from the default.

If the VPS has an IPv6 address, add a second ORPort line. Tor cannot bind to "any" IPv6 address the way it does for IPv4, so write the address out in square brackets.

ORPort 9001
ORPort [2001:db8::1]:9001

On a 1 GB VPS, add MaxMemInQueues 512 MB. Tor decides its queue limit from the memory it sees on the machine, which on a small shared box is more than you want it to use. Setting the limit yourself makes tor discard queued cells under pressure, which the relay survives, instead of growing until the kernel kills the process.

Open the ORPort in the firewall

Inbound, the ORPort must be reachable from anywhere on the internet. Outbound, leave the relay unrestricted: it opens connections to thousands of other relays on many different ports, and an outbound allowlist will quietly cripple it.

sudo ufw allow 9001/tcp comment 'tor ORPort'
sudo ufw status verbose

Then check the provider's own network firewall. Many control panels run a packet filter in front of the virtual machine, and a rule you added with ufw has no effect there, so the port reads as open on the box and closed from outside. If ufw is new to you, the ufw rules that belong on every VPS walks through the default policy and the order rules are matched in.

Size the bandwidth to your plan

The manual describes RelayBandwidthRate as a separate token bucket that limits "the average incoming bandwidth usage for relayed traffic on this node to the specified number of bytes per second, and the average outgoing bandwidth usage to that same value". Read that twice. The limit applies to each direction separately. A relay set to 1 Mbit/s can move 1 Mbit/s in and 1 Mbit/s out at the same time, and a provider that meters both directions bills the sum.

ChartMonthly traffic at a sustained relay rate, both directions, 30 days
The data behind this chart
[
  {
    "label": "1 Mbit/s",
    "torrc_rate": "125 KBytes",
    "gb_per_day": 21.6,
    "gb_per_month": "648"
  },
  {
    "label": "2 Mbit/s",
    "torrc_rate": "250 KBytes",
    "gb_per_day": 43.2,
    "gb_per_month": "1,296"
  },
  {
    "label": "5 Mbit/s",
    "torrc_rate": "625 KBytes",
    "gb_per_day": 108,
    "gb_per_month": "3,240"
  },
  {
    "label": "10 Mbit/s",
    "torrc_rate": "1250 KBytes",
    "gb_per_day": 216,
    "gb_per_month": "6,480"
  },
  {
    "label": "20 Mbit/s",
    "torrc_rate": "2500 KBytes",
    "gb_per_day": 432,
    "gb_per_month": "12,960"
  }
]

Those 5 rows are arithmetic, not a measurement: they show what a rate costs if the relay sustains it for a full 30 days in both directions. A real relay sits under its cap much of the time, especially in the first weeks. Use the table to rule out settings that cannot fit, not to predict an invoice to the gigabyte.

At 1 Mbit/s each way a relay moves about 21.6 GB a day, so a 30 day month costs roughly 648 GB of metered traffic. That fits inside a 1 TB allowance with room left for updates and backups. Step up to 2 Mbit/s and the month costs 1,296 GB, which is already past a 1 TB plan. The last row, 20 Mbit/s, needs 12,960 GB a month and belongs on an unmetered port. If your provider bills outbound traffic only, halve every figure. Find out which one you have before you set the rate, because the two answers differ by a factor of two.

Now the config. Rate limit first, quota second.

RelayBandwidthRate 125 KBytes
RelayBandwidthBurst 250 KBytes
AccountingMax 400 GBytes
AccountingRule sum
AccountingStart month 1 00:00

RelayBandwidthBurst is the size of the token bucket, so it allows short spikes above the rate while the average holds. About twice the rate is a sane value.

AccountingRule is the line most operators miss. The default is max, which measures the larger of the two directions against the quota. With the default, AccountingMax 400 GBytes permits 400 GB in and 400 GB out, which is 800 GB on a meter that counts both. AccountingRule sum counts read plus write against the one quota, which is what a transfer allowance actually measures.

Write AccountingStart as well, never AccountingMax on its own. The quota is the number, and the start line is the period it resets on. A quota with no period leaves the relay hibernating with nothing to bring it back.

Hibernation is a blunt instrument. When the quota runs out, tor logs this and stops taking work:

Bandwidth soft limit reached; commencing hibernation. No new connections will be accepted

The relay does not wake at the exact start of the next period either. Tor tracks how fast it burned the last quota and picks a random point inside the new interval, so that thousands of relays do not return to the network at the same second. A relay that disappears for the last week of every month keeps losing the stability the directory authorities measure it on. Size RelayBandwidthRate so the cap is never reached, and keep AccountingMax as the backstop that protects the invoice.

Start the relay and confirm it is reachable

sudo systemctl restart tor@default
sudo systemctl status tor@default
sudo journalctl -u tor@default -n 50

Within a few minutes the log should contain this line:

Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.

That sentence means other relays connected back to your ORPort and built a circuit through it. Until it appears, your relay is not in the directory and carries nothing at all. The failure reads like this:

Your server has not managed to confirm reachability for its ORPort(s) at 203.0.113.10:9001. Relays do not publish descriptors until their ORPort and DirPort are reachable. Please check your firewalls, ports, address, /etc/hosts file, etc.

Work through it in order. Is the ORPort open in ufw. Is it also open in the provider's separate network firewall. Is the address in that message the address the internet actually routes to you, rather than a private address from a NAT setup. Test the port from a different machine with nc -vz 203.0.113.10 9001. Tor repeats the self test on its own, so a fixed firewall is noticed without your help, and a restart makes it immediate.

Your relay's permanent identity is its fingerprint:

sudo cat /var/lib/tor/fingerprint

Roughly three hours after the descriptor is published, the relay appears on Relay Search. Search the nickname or paste the fingerprint. That page is what the network thinks of your relay: which flags it holds, what weight the authorities give it, and which version it is publishing.

Why does a new Tor relay carry almost no traffic?

Because the network has not measured it yet, and measurement takes weeks. The Tor Project describes the ramp in four phases, and an operator who has not read it concludes the relay is broken and starts changing things.

For the first three days the relay is unmeasured. It reports its own self test result, and the directory authorities cap the published weight at 20 KB anyway, so clients almost never pick it. From about day three to day eight the bandwidth authorities measure it for real and the weight climbs, but it is used only as a middle hop, because no client is willing to make a brand new relay its first hop.

Around day eight the relay becomes eligible for the Guard flag. Getting the flag makes traffic drop, which surprises everyone: clients skip guards when choosing middle hops, assuming a guard is already busy, so the relay loses middle traffic before it gains guard traffic. It refills only as clients rotate their guard sets, which takes weeks. By roughly day 68 it reaches a steady state, where the clients dropping it balance the clients adding it.

So the honest expectation is nothing for three days, something after a week, and a real load after two months. Change one setting, then wait a week to see what it did. A self-hosted Uptime Kuma status page with a TCP check against port 9001 is a better use of the nervous energy: it answers the question you can actually control, which is whether the port is still answering.

Watch the relay with nyx

nyx is the terminal monitor for a running relay. It talks to tor's control port, so enable that first in torrc:

ControlPort 9051
CookieAuthentication 1
CookieAuthFileGroupReadable 1

ControlPort listens on 127.0.0.1 only, and cookie authentication means a program must read a secret file before it can issue commands. Tor writes that cookie to /run/tor/control.authcookie as the debian-tor user, mode 600, so nothing else can read it. CookieAuthFileGroupReadable 1 opens it to the group, which is what lets your own account run nyx without sudo.

sudo apt install -y nyx
sudo adduser "$USER" debian-tor
sudo systemctl restart tor@default

Log out and back in, then run nyx. The new group has to be picked up at login, so running nyx in the same shell session gives a permission error on the cookie file even though the config is right. nyx shows live bandwidth, uptime, the log stream and the connection list. In the first weeks the number to watch is the bandwidth graph staying under your RelayBandwidthRate.

Running more than one relay: MyFamily and family keys

With a single relay, skip this section. Two or more relays run by the same operator must declare each other, so that clients never build a circuit that enters and leaves through your machines, which would let one operator see both ends of it.

The long-standing way is MyFamily in every relay's torrc, listing the fingerprints of all the others:

MyFamily AAAAAAAAAA,BBBBBBBB

Every relay lists every other one, so adding a fourth relay means editing four files. Tor 0.4.9 replaced that with a family key. Generate one key, then share it:

tor --keygen-family myfamily

That writes myfamily.secret_family_key and prints a FamilyId line. Copy the key file to every relay, into the keys subdirectory of the DataDirectory (/var/lib/tor/keys on Debian and Ubuntu), keeping the .secret_family_key suffix. Add the printed FamilyId line to each torrc and reload with sudo systemctl reload tor@default. Keep the MyFamily list in place as well for now. Clients that do not yet understand family certificates still read the legacy list, and the Tor Project will announce when it can be dropped.

What breaks after it is running

The version goes stale. Unattended upgrades replace the package, but the running process keeps the binary it started with until something restarts it. Compare tor --version on the box with the version shown on the relay's Relay Search page. If they differ, the network is still seeing the old one, so restart the service.

The clock drifts. Consensus documents and certificates are all time-bound, so a machine whose clock is far out rejects the consensus and stops publishing. timedatectl should report the system clock as synchronized. If it does not, enable systemd-timesyncd or install chrony.

The IP address changes. The descriptor carries the address, and clients cannot reach an address that has moved. After any provider migration or address change, restart tor and watch for the self-test line again.

The relay is slower than the plan allows. Tor's relay crypto is efficient on modern processors, and the Tor Project puts a CPU with AES-NI support at roughly 400 to 450 Mbit/s in each direction. Long before that ceiling you are limited by the port speed and the transfer allowance, which is why the accounting section above matters more than the hardware.

FAQ

How much bandwidth does a Tor relay use?

As much as you allow it, and no more. RelayBandwidthRate caps relayed traffic in each direction separately, so a relay set to 1 Mbit/s can carry 1 Mbit/s in and 1 Mbit/s out at once. That works out to about 21.6 GB a day, or 648 GB across a 30 day month, counting both directions. Add AccountingMax with AccountingRule sum as a hard monthly quota underneath that rate.

Will running a Tor relay get me abuse complaints?

A guard or middle relay passes traffic only to other Tor relays and never connects to a website for a user, so complaints about what someone did through Tor go to the exit operator, not to you. What you may see is scanning and the occasional IP reputation listing, because the address is publicly listed as a relay. Exit relays are the ones that receive abuse mail and legal notices, and they need a provider that has agreed in advance to handle it. Read your provider's terms before starting either kind.

Why is my new Tor relay not getting any traffic?

Because new relays are throttled by design until they are measured. For the first three days the directory authorities cap the published weight at 20 KB, so clients almost never choose the relay. Bandwidth authorities measure it from about day three, it becomes eligible for the Guard flag around day eight, and traffic dips again at that point because clients avoid guards when picking middle hops. Full load arrives around day 68. Confirm the log shows "Self-testing indicates your ORPort is reachable from the outside", then leave it alone.

Can I run a Tor relay on a VPS with a 1 TB transfer allowance?

Yes, at about 1 Mbit/s in each direction, which is RelayBandwidthRate 125 KBytes. That comes to roughly 648 GB a month if your provider meters both directions, leaving headroom for updates and backups. Add AccountingMax 400 GBytes with AccountingRule sum and AccountingStart month 1 00:00 so the relay hibernates instead of overrunning the plan. If the provider bills outbound only, you can double the rate.

Do I need to set MyFamily if I run only one relay?

No. Family declarations exist so that clients avoid building a circuit through two relays owned by the same operator, which is meaningless with one relay. Set it as soon as you add a second: list every relay's fingerprint in every relay's MyFamily line, or use the family key that Tor 0.4.9 introduced, which distributes one FamilyId instead of an ever-growing list.