en

OnionBalance: High-Availability Onion Services Across Multiple VPS

A single onion service runs on one machine, so if that machine reboots, gets seized, or simply saturates, your .onion address goes dark. OnionBalance solves this by letting one public .onion address be served by several independent backend VPS at once, giving you both failover and crude load distribution without changing the address your visitors bookmark. This guide explains how the v3 descriptor mechanism actually works, how to lay it out across offshore VPS, and the key-management and descriptor-publishing mistakes that quietly take the whole service offline.

Need this done for your project?

We implement, you ship. Async, documented, done in days.

Start a Brief

What OnionBalance actually does (and what it does not)

An onion service advertises itself to the network by publishing a signed descriptor to a rotating set of hidden service directories (HSDirs). That descriptor lists the service's introduction points: a handful of relays that act as rendezvous brokers. A client that knows your address fetches the descriptor, picks an introduction point, and negotiates a rendezvous. The whole reachability of a .onion address therefore reduces to one question: is there a valid descriptor in the HSDir hash ring that lists working introduction points?

OnionBalance exploits exactly this. Instead of one server publishing its own descriptor, you run several independent backend onion services, each on its own VPS, each with its own keys and its own introduction points. A separate, lightweight management instance collects the introduction points from every backend, merges them into a single descriptor signed with the master identity key, and publishes that combined descriptor under your public address. A client connecting to your public .onion is transparently routed to whichever backend's introduction point it happened to select.

Two consequences follow, and it is important to be honest about both:

  • It gives you redundancy. If one backend VPS dies, its introduction points stop responding, and (after the next descriptor refresh) clients land on the survivors. The address never changes.
  • It gives you only coarse load spreading, not real load balancing. A descriptor can advertise at most around 10 to 20 introduction points total, and a client picks one at random. There is no health-aware routing, no session affinity, and no awareness of which backend is busy. Treat OnionBalance as availability insurance, not as a precise load balancer.

Critically, the management instance is not in the data path. Once a descriptor is published, clients talk directly to a backend; the management host can be offline for hours and existing descriptors keep working until they expire. That makes the management instance an attractive, low-exposure component to run on a small, separate VPS.

The v3 architecture: master key vs. backend keys

OnionBalance v3 (the only version that matters now that v2 onion services are fully deprecated and removed from Tor) draws a deliberate line between two kinds of keys, and getting this distinction right is the whole game.

  • The master key is the ed25519 identity that is your public .onion address. It lives only on the OnionBalance management instance. It is used to sign the combined descriptor. It should never be copied onto a backend.
  • The backend keys are entirely separate onion-service identities, one per backend VPS. Each backend is just a normal, standalone onion service with its own address that nobody publishes or advertises. OnionBalance reads the introduction points those backends publish and folds them into the master descriptor.

The practical layout is therefore: N backend VPS, each running tor with a vanilla v3 HiddenServiceDir pointing at your actual application (a web server, for example), plus one management VPS running tor and the onionbalance daemon. To create the master key, generate a fresh v3 onion service once and keep its hs_ed25519_secret_key; OnionBalance ships a helper, onionbalance-config, that scaffolds the config and can generate this key for you.

# on the management VPS, scaffold a config and master key
onionbalance-config -n 3   # 3 backends

# this produces:
#   master/                 (your public address + its secret key)
#   instance_0..2/          (placeholder backend addresses to fill in)
#   config.yaml             (lists the backend onion addresses)

You then edit config.yaml so each instance entry holds the real backend .onion address of each VPS (the address that VPS's own tor generated), not a placeholder. The management config does not need the backend secret keys at all; it only needs to know the backend addresses so it can fetch their descriptors from the network. This is the cleanest property of the design: the management instance holds exactly one secret (the master key) and nothing else.

A typical config.yaml stanza:

services:
  - key: master/hs_ed25519_secret_key
    instances:
      - address: backenda...d.onion
      - address: backendb...d.onion
      - address: backendc...d.onion

Run the daemon with onionbalance -c config.yaml. It connects to its local tor over the control port, gathers the three backend descriptors from the HSDirs, builds one descriptor advertising the union of their introduction points, signs it with the master key, and publishes it. From then on it refreshes on a timer.

Laying it out across offshore VPS

The redundancy is only real if your backends fail independently. Three backends in the same rack behind one upstream router are one power event away from going dark together, and OnionBalance will dutifully publish a descriptor full of dead introduction points. Spread the backends across different machines, ideally different networks and jurisdictions. AnubizHost VPS in separate locations make natural, independent backends; running them in different countries also means a legal or network action against one host does not take the address with it. See the full range on the offshore VPS plans, and consider a heavier backend or two from the offshore dedicated servers if a single backend must absorb real traffic.

Resource-wise the components are asymmetric:

  • Backends carry the actual traffic and run your application stack, so size them for the workload. For a static or low-traffic onion site, 1 vCPU / 1 GB RAM per backend is plenty; the Romania plan from $19.99/mo is a sensible per-backend unit.
  • The management instance does almost nothing: it runs tor plus a tiny Python daemon and publishes a small descriptor every few minutes. The smallest VPS you offer is sufficient, and because it is not in the data path it can live on a cheap, quiet host.

Each backend's tor config is ordinary. On a backend VPS:

HiddenServiceDir /var/lib/tor/backend/
HiddenServicePort 80 127.0.0.1:8080
# v3 is the default; do not set HiddenServiceVersion 2

The management VPS's tor needs a reachable control port so the daemon can publish descriptors:

ControlPort 127.0.0.1:9051
CookieAuthentication 1
# OnionBalance authenticates to tor over this control port

One operational nicety: because every backend serves identical content under a different hidden address, you can also hand out the individual backend addresses to power users or monitoring, while ordinary visitors only ever see the master address. That gives you a way to probe each backend's health directly, which OnionBalance itself will not do for you.

Descriptor-publishing and key-management pitfalls

OnionBalance fails in quiet, non-obvious ways. The service does not crash; it simply publishes a descriptor that does not work, and you find out from users. These are the traps worth internalizing before you rely on it.

  • Descriptor staleness vs. fast failover. A v3 descriptor is valid for up to roughly three hours, and clients cache it. If a backend dies, clients holding a cached descriptor keep trying its dead introduction points until the descriptor refreshes. OnionBalance republishes well within the validity window, but there is an unavoidable failover window of minutes, not milliseconds. Plan around it; do not promise zero-downtime cutover.
  • Introduction-point budget. Each backend contributes its introduction points, but the combined descriptor has a hard ceiling on how many it can advertise. With many backends, OnionBalance samples a subset, so adding a tenth backend does not linearly add capacity, it dilutes representation. Two to four well-placed backends usually beat eight cramped ones.
  • Clock skew breaks signatures. Descriptor signing and the HSDir hash ring are time-sensitive. If the management instance's clock drifts, it can compute the wrong responsible HSDirs or sign with the wrong time period, and the descriptor becomes unfetchable. Run NTP (chrony) on the management VPS and treat clock health as a hard dependency.
  • The master key is the single point of compromise. Whoever holds master/hs_ed25519_secret_key controls the address. Back it up offline and protect it like a TLS private key, but never distribute it to backends. A leaked master key means an attacker can publish their own descriptor for your address; rotating it means a new .onion address entirely.
  • Backends must not advertise themselves. A backend is a plain onion service, but if you publish or link its individual address, you have created a second public entry point that bypasses the balancing entirely and leaks your topology. Keep backend addresses internal.
  • The management instance needs the control port, not the data port. A common setup error is omitting ControlPort/CookieAuthentication on the management tor, which leaves OnionBalance unable to publish at all. Confirm the daemon's logs show successful descriptor uploads, not just a clean start.

Verify the whole thing the boring way: take down one backend deliberately, wait out a descriptor refresh, and confirm the address still resolves through the survivors. An untested failover is not a failover.

Privacy & anti-censorship guides

Why Anubiz Host

100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included

Ready to get started?

Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.

Anubiz Chat AI

Online
OnionBalance: High-Availability Onion Services on VPS | Anubiz Host