---
title: Operate an active-passive pair
label: High availability
description: Share or replicate persistent state while ensuring that only one VOTPort instance writes it.
layout: docs
order: 280
---

VOTPort supports one live instance and a passive standby. Both hosts need the same release, configured paths, and access to the received and outbound files. Plan and rehearse promotion before relying on failover.

## Shared storage

The live instance persists state in `data/`, `/received`, and `/outbound`. A standby that takes over those same paths sees the existing links, tenants, settings, receipt identity, and resumable uploads.

- Keep `data/` on storage with exactly one writer, such as a block volume that moves with the service. SQLite on NFS is unsupported.
- `/received` and `/outbound` may use shared network storage under the [storage guide's requirements](/docs/self-hosting/storage/).
- Fence the previous host before promoting the standby. Two hosts writing one database can corrupt it.

An exclusive lock on `data/lock` prevents overlapping writers on supported local or shared block storage. `/received/.vot-stage/writer.lock` is a permanent inode holding a server-coordinated exclusive kernel lock. The diagnostic heartbeat in `.vot-stage/.votport-lease` refreshes every 30 seconds; an old timestamp or a different wall clock never authorizes takeover.

A clean stop releases the kernel lock. After a crash, follow the NAS lock-recovery rules. Never unlink the lock file: doing so can create independent lock inodes and overlapping writers. Stop or fence the old host first. Ownership loss stops writes and preserves recovery state; a blocked hard-NFS operation can remain in the kernel, so do not infer safety from elapsed time. See [direct receiving ownership](/docs/self-hosting/direct-receiving/#protect-writer-ownership).

## Replicated standby

When the data volume cannot move between hosts, run the standby in replica mode:

```sh
votport standby
```

Configure these variables on that host:

| Variable                        | Value                                                                    |
| ------------------------------- | ------------------------------------------------------------------------ |
| `VOTPORT_STANDBY_SOURCE`        | The live instance's HTTPS origin                                         |
| `VOTPORT_REPLICA_TOKEN`         | The token configured under System / Standby replica on the live instance |
| `VOTPORT_DATA_DIR`              | The standby's persistent data directory                                  |
| `VOTPORT_STANDBY_INTERVAL_SECS` | Pull interval, default 60 seconds                                        |

The standby pulls and validates database and identity snapshots, staging the latest successful snapshot for its next normal boot. It does not open the live database or write to the receive root.

Replica mode reports healthy through `/healthz` while successful pulls remain within two intervals. `/readyz` stays unavailable and reports replica lag. Do not place a replica-mode process in a serving proxy pool.

## Promote and recover

1. Fence or stop the old live instance and confirm that it cannot resume writing.
2. Check the standby's replica lag and the availability of the shared receive and outbound paths.
3. Stop the replica process, then start `votport` normally with the same data directory.
4. Check readiness, sign in again, and verify an existing link and a representative transfer before directing traffic to it.

Promotion rotates administrative session credentials; receipt and native-transfer identities carry over. Changes after the last successful replica pull are outside the recovered snapshot, and uploads in that window may need to start again. Choose the interval around the amount of recent work you can afford to recover manually.

If promotion is interrupted during restoration, finish a normal VOTPort boot before returning that directory to standby mode. Upgrade the standby binary before the live binary: it refuses snapshots from a newer database schema.

## Monitor the pair

Monitor `/readyz`, replica lag, and the `votport_lease_held` and `votport_lease_age_seconds` metrics. A proxy can health-check a shared-volume standby once it starts serving; a replica-mode standby must first be promoted. Use `/healthz` for proxy liveness so a drained instance can continue serving downloads while it shuts down gracefully.
