Hardware sizing for coordinators and mining workers, on Compose or the appliance image.
| Arrangement | Services and miner connection | Requirements |
|---|---|---|
| Coordinator-only | P2Pool, XMRig proxy, Tor, dashboard and supporting services; Monero and optional Tari nodes run here unless configured remote. Separate workers connect to its advertised stratum endpoint, port 3333 by default. |
The stack-host budget below follows the local nodes; allow storage for sync, growth and migration, and keep the coordinator reachable by its workers. |
| Coordinator plus local worker | The same coordinator, plus an opt-in XMRig worker on its CPU, connected to its own stratum over loopback. Separate workers can connect too. | The coordinator budget still applies, plus CPU and memory headroom for the miner. Installer support alone does not establish useful co-located performance. Follow local-worker setup and cap miner threads to leave room for nodes. |
| Worker-only | XMRig through RigForge, connected to an existing coordinator. No chains, P2Pool, coordinator dashboard or stack containers run on the worker. | Use RigForge's worker hardware requirements, not the chain-storage budget below. Allow space for the OS and miner, and network access to the coordinator; the appliance requires wired ethernet. |
The appliance's role chooser currently displays Pithead, Pithead + RigForge and RigForge. The middle choice is the coordinator configuration with its local-miner switch enabled, not a third runtime role. Compose installs the coordinator; local mining requires a separate host RigForge installation. Worker-only uses RigForge directly or the appliance's rig role, not a worker-only Compose stack.
Separate workers are the recommended scale path: size the coordinator for nodes, storage and uptime, and workers for CPU mining. Co-location does not promise spare-capacity scheduling or no impact on other workloads. The pending co-location measurement and shared-host guide own those results. For miner connection instructions, see Connecting Miners.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores, 64-bit x86 (AVX2 advised) | 6–8+ cores with AVX2 |
| RAM | 16 GB | 32 GB |
| Disk — pruned node | 600 GB+ SSD | 1 TB+ SSD |
| Disk — full node | 600 GB+ SSD | 2 TB+ SSD |
| Network | Always-on broadband | Unmetered broadband |
| OS | Ubuntu Server 24.04 LTS | Ubuntu Server 24.04 LTS |
These figures assume the default configuration: both nodes local, Monero pruned, HugePages enabled. Pointing either node at a machine you already run lowers them a lot — Monero is the bigger cut. See Running a node elsewhere.
The host runs several services in one box, so its requirement is the sum of what each service needs plus headroom for the OS. Per-component breakdown, from each project's own guidance:
| Service | RAM it wants | Container ceiling | Disk | Notes |
|---|---|---|---|---|
Monero node (monerod) |
4 GB minimum; more RAM = bigger DB cache and faster sync | 6 GB (monero.mem_limit) |
~286 GB fresh-sync pruned, September 2026 · ~267 GB full observed, not a provisioning guarantee — and growing | SSD strongly recommended. Not run at all with monero.mode: remote. |
| P2Pool | ~2.3 GB for the RandomX dataset it uses to verify blocks fast | 4 GB | tiny (sidechain state) | Needs a 64-bit CPU with AVX2 and a synced monerod. The dataset lives in the shared HugePages reservation, not in the container, so don't count it twice. When the reservation has too few free pages, P2Pool puts the dataset in ordinary memory instead (about 2.5 GB); the ceiling leaves room for that. |
Tari base node (minotari_node) |
4 GB minimum, 8 GB+ recommended; grows over time | auto (tari.mem_limit) |
~150 GB estimate SSD — and growing | Budget for it whenever it runs here. The stack caps its memory so growth can't take the host down. Not run at all with tari.mode: remote or off. |
| XMRig proxy · Tor · dashboard | a few hundred MB combined | 512 MB each | a few GB (Docker images) | These coordinate and serve the UI. They don't mine, so no special CPU. |
| Caddy · Docker socket proxies | small | 128 MB each | — | Serve the dashboard and mediate its Docker access. |
Payout confirmation (wallet-rpc, tari-wallet) |
only when enabled | 2 GB · 512 MB | small (view-only wallet state) | Started only when monero.view_key / tari.view_key are set — and both are refused in that node's remote mode, since the scan needs a local node. |
Add the three heavy services' RAM (Monero 4 GB, P2Pool ~2.3 GB, Tari 4 GB) plus a couple of GB for the OS, page cache, and supporting containers, and you reach the 16 GB minimum above.
Disk is dominated by the two chains. Setup budgets 320 GiB for Monero and 200 GiB for Tari, plus
8 GiB for P2Pool, the dashboard, and Tor. Use the same Monero budget in either prune mode: our current live
measurements do not support a smaller safe budget for a normally pruned node. Pruning an existing
full chain also does not reclaim LMDB free pages in place; measure the freelist before deciding a
rewrite with monero-blockchain-prune can reclaim space. Stop monerod first: the tool moves the new
DB into place itself, renaming the old chain aside, and it will do that under a running daemon.
Both chains keep growing; ~100+ GB/year combined is a planning estimate, not a measured forecast.
That's why the table lists a 600 GB minimum and
recommends more: for a set-and-forget host, put it on a 2–4 TB SSD. In September 2026, a Monero node
synced from genesis with pruning enabled consumed 285.8 GB. Its first startup logged the branch that
Monero 0.18.5.1 enters only when the database has no pruning seed; that branch runs the prune
operation, which writes the seed, before synchronization starts
(core,
LMDB).
The file occupies 285.8 GB whether its pages are live data or reusable LMDB high-water space, so its
unread freelist does not make the old 120 GiB disk budget safe. A separate bench copy measured
276.9 GB with only 10 free pages out of 67,605,667
(#1502).
./pithead setup therefore budgets 320 GiB for Monero in either mode and 200 GiB for Tari. The
per-service RAM figures are provisioning minimums — steady-state resident memory is much lower
(monerod and P2Pool a few hundred MB each, since their large data lives in the shared HugePages and
in reclaimable page cache; Tari 2–4 GB and climbing), so size for the minimums, not today's usage.
The container ceilings are runaway protection, not reservations: nothing is set aside up front, and each container runs with swap disabled so a leak is OOM-killed and restarted on its own instead of dragging the host down with it.
NOTE: Monero and P2Pool both want large memory pages for RandomX, so they share one ~6 GB HugePages reservation rather than each adding their own. See Memory for what that means for the 16 GB floor.
The coordinator CPU runs the nodes, P2Pool's block verification, the proxy and the dashboard. Without a local worker it need not be a high-end mining chip; with one, leave CPU and memory headroom for those services. Two things matter for the coordinator:
- AVX2 is strongly recommended. P2Pool verifies blocks with RandomX, which runs far better with AVX2; setup warns "AVX2 not detected. Mining performance will be poor." if it's missing. (P2Pool also requires a 64-bit CPU; ARMv7 and older aren't supported.)
- More cores speed up the first sync. Monero parallelizes block verification during the initial sync:
monero.prep_blocks_threadsdefaults toauto= host cores − 2, clamped to 4–8. So 6–10 cores use the full thread budget while leaving headroom for the rest of the stack. Steady-state CPU load after the initial sync is low.
16 GB is the practical floor with the default configuration. The budget:
- ~6 GB reserved for HugePages. RandomX wants large pages, so setup configures
vm.nr_hugepages=3072(3072 × 2 MB = 6 GB), shared bymonerodand P2Pool. This RAM is carved out of the kernel up front and is invisible to container memory stats; it's gone whether or not it's fully used. - Tari (4 GB+, growing) gets an auto-sized ceiling (
tari.mem_limit: auto) so a runaway restarts cleanly instead of taking the host down. On a 16 GB host that ceiling is ~7.5 GB; on 32 GB, ~19 GB. - The OS, page cache, and the lighter containers take the rest.
On a 16 GB machine this fits but is tight, which is why Tari is capped. Use 32 GB if you run a full
(unpruned) node, drive many workers, or want long uptimes without Tari's growth pressing on the cap.
With tari.mode: remote there is no Tari container to cap, so that term leaves the budget entirely —
see Running a node elsewhere.
Running with only 8 GB? It boots only if you disable HugePages (
./pithead setup --skip-optimize), which frees the 6 GB reservation, but leaves little headroom and hurts RandomX verification performance. Watch what else that changes: with no reservation to subtract, Tari's auto ceiling becomes ~75% of total RAM — 6 GB of an 8 GB host. On a host that small, settari.mem_limitby hand (e.g."3g"), or runtari.mode: remoteand leave the memory tomonerodand P2Pool. Prefer 16 GB+.The appliance makes this call itself: 16 GB is its supported floor, and on a machine below it the boot shrinks the reservation to 4 GB, sized from a measured run rather than a derivation — see
os/KNOWN-ISSUES.md(#2685) for the peaks. It announces this on the console, anddoctorreports it as a warning until the machine has 16 GB. Far below the floor (under ~7 GB) the reservation is released entirely and the stack will not run reliably.
The two blockchains dominate, and an SSD is strongly recommended: initial-sync verification and the node databases do heavy random I/O that punishes spinning disks. What to provision:
| Pruned (default) | Full (monero.prune: false) |
|
|---|---|---|
| Monero chain | ~286 GB fresh-sync, September 2026 | ~267 GB observed; not a provisioning guarantee |
| Tari chain | ~150 GB estimate | ~150 GB estimate |
| P2Pool + dashboard + Docker images | a few GB | a few GB |
| Plan for | 600 GB+ SSD | 600 GB+ SSD |
Both chains keep growing; allow for the estimated ~100+ GB/year combined rather than treating these observations as fixed sizes. Leave headroom: the recommended 1 TB+ (pruned) / 2 TB+ (full) sizes exist for that, and a 2–4 TB SSD is the set-and-forget choice. Tari's chain (~150 GB) is the same whether or not you prune Monero. Pruning (the default) keeps a fully validating Monero node while discarding eligible prunable transaction data. The live observations above are why the disk budget is currently the same in either mode. Sync and database migration need free space too: a migrating Tari upgrade requires room beside the old database for a compacted copy, checked as its current size plus 5 GiB. See Updating the stack before sizing an existing data volume for an update.
A node running elsewhere is left out of this budget entirely — see Running a node elsewhere for the totals in each combination.
setuppre-flights these. Before a sync,./pithead setupwarns if the host falls short; it never blocks. Disk is checked per filesystem rather than as one total: the data dirs are grouped by the volume they sit on, and each volume is compared against the combined need of the components sharing it — so splitting chains across disks is measured as you actually laid it out. The budget follows the modes you configured, and a node set toremoteis left out of it entirely. The RAM check does not: it warns below 16 GB whatever the modes, so a deliberately small remote-node host sees that warning and can ignore it.
./pithead doctorre-runs the same disk check on demand, and adds a live memory check rather than repeating setup's: it warns when the HugePages reservation is missing or smaller than this machine's budget (3072 pages, or the appliance's reduced pool on a low-RAM machine, never less than the 1296 pages of P2Pool's RandomX dataset and its two caches), and when free memory is under 2 GB right now. A pool too small for P2Pool's RandomX dataset (1040 pages, about 2 GiB) matters most: P2Pool then puts the dataset and its caches in ordinary RAM, up to about 2.5 GB that its 4 GB memory limit holds but the rest of the machine loses. In a larger pool that is still short of the budget the same can happen when monerod's own RandomX pages leave fewer than 1040 free as P2Pool starts. doctor reports a short pool as a warning rather than a failure, because the appliance's boot-time commit gate for an update takes doctor's exit code. Setup asks whether the host has enough RAM at all; doctor asks whether enough is free today.
You can put any service's data on a dedicated disk by pointing its *.data_dir at an absolute path,
e.g. to keep the Monero blockchain on a separate SSD. See
Configuration › Data directories.
- Always-on broadband. With both nodes local, all upstream traffic (Monero, Tari, P2Pool) goes over Tor, with no public port forwarding required; the stack uses hidden services for inbound peers. A node you point at over the network is the exception — that leg is a direct connection, so keep it on the LAN or behind WireGuard (Privacy › Runtime egress).
- Initial sync is the heavy part. The first run downloads and verifies both chains over Tor (slower
than clearnet). A fresh pruned sync produced a ~286 GB Monero database in September 2026; Tari
measured ~150 GB. This takes a few hours to a day or more. A node in
remotemode syncs nothing here, so its share drops out. Avoid it by reusing an existing synced node, or speed it up with an optional clearnet initial sync (default off, privacy-relevant) that downloads over clearnet and then returns to Tor. - Steady state is light. Once synced, bandwidth is modest.
- LAN reachability for workers. Each worker rig connects to the host on port 3333 over the local
network (plain stratum, not Tor). If the host has a firewall, allow inbound
3333from the LAN.
-
Ubuntu Server 24.04 LTS is the officially supported platform. Other Linux distros may work but aren't officially supported. macOS is deprecated as of 2026-09-10: the installer refuses it, the test suite refuses to run on it, and the remaining Darwin code paths are untested.
-
The kernel/HugePages tuning is Linux-only. On Linux, making HugePages persistent edits GRUB and needs a reboot (you're prompted first, and can skip with
--skip-optimize). -
Required software: Docker Engine, Docker Compose v2,
jq, andopenssl. On Ubuntu,./pithead setupoffers to install anything missing, or do it yourself:sudo apt update && sudo apt install -y jq docker.io docker-compose-v2 openssl python3
The defaults assume a self-hosted, pruned, HugePages-tuned local node. You can trade some away:
| Want to… | Do this | Saves |
|---|---|---|
| Skip the Tari node entirely | tari.mode: remote merge-mines against a node elsewhere; tari.mode: off declines merge-mining altogether. Either way the bundled minotari_node isn't started |
200 GiB disk budget + Tari's RAM ceiling |
| Skip the Monero node entirely | monero.mode: remote; the bundled monerod isn't started |
320 GiB disk budget + Monero's 4 GB RAM |
| Skip the initial sync wait | Reuse an existing synced chain | Hours–days + sync bandwidth |
| Free the 6 GB HugePages reservation | ./pithead setup --skip-optimize |
~6 GB RAM (at the cost of RandomX performance). The reservation is unconditional otherwise — remote-node modes don't shrink it, since P2Pool still verifies blocks with RandomX |
| Free RAM for other apps | Lower tari.mem_limit (e.g. "4g") |
Caps Tari's ceiling lower |
| Keep mining while Tari resyncs | dashboard.tari_required: false |
A Tari resync stops blocking Monero mining (Tari outages never block it, either setting) |
Either chain can live on another machine. monero.mode: remote and tari.mode: remote each drop
that node's container from the stack: it is never started, its data directory is left out of the
disk budget, and its chain is never synced here. Everything else — P2Pool, the XMRig proxy, the
dashboard, and Tor — still runs locally in every combination.
Monero is the larger current disk saving (320 GiB, against Tari's 200 GiB). Free disk setup and
doctor ask for, by combination:
| Monero | Tari | Disk budget on this host |
|---|---|---|
| local, pruned (default) | local (default) | 528 GiB |
| local, full | local | 528 GiB |
| local, pruned | remote | 328 GiB |
| local, full | remote | 328 GiB |
| remote | local | 208 GiB |
| remote | remote | 8 GiB (P2Pool, dashboard, Tor, Docker images) |
Those are free-space checks, not SSD label sizes: 528 GiB is about 567 GB, and 328 GiB is about 352 GB. Buy at least 600 GB for both nodes local, or 370 GB with Tari remote and Monero local.
What a remote Tari node changes beyond disk:
- RAM. No
minotari_nodecontainer, so nothing is capped bytari.mem_limitand Tari's 4 GB+ drops out of the memory sum behind the 16 GB floor. The 6 GB HugePages reservation,monerod, and P2Pool are unchanged, so HugePages remains the largest single claim on the host. - Initial sync. No Tari chain to download or verify here — roughly 150 GB less over Tor on the first run, and the sync wait shrinks to Monero's.
- Network. P2Pool's merge-mining gRPC to that node is a direct connection, not a Tor circuit, and it is plaintext and unauthenticated. Keep the node on your LAN or behind WireGuard. See Privacy › Runtime egress.
- Tor. No inbound onion is published for a node that isn't here, so a remote-mode host serves one fewer hidden service.
Either way it must be a node you control, and the requirements differ per chain. See Connecting to a remote Monero node and Remote Tari node — including how to make this stack the serving side for another one.
NOTE: on-chain payout confirmation scans against local nodes only, so
monero.view_keyis refused withmonero.mode: remoteandtari.view_keywithtari.mode: remote. Setup fails with that reason rather than scanning through someone else's daemon.
- Small home setup (pruned): a 6-core / 16 GB / 1 TB SSD mini-PC as the host, HugePages on, with one or two workers pointed at it.
- Full node + several workers: an 8-core / 32 GB / 2 TB SSD host running an unpruned node, feeding a handful of dedicated mining rigs. Headroom for Tari growth and long uptimes.
- Small disk, Tari elsewhere: a 400 GB mini-PC can host a pruned Monero node with
tari.mode: remotepointed at a Tari node on the LAN — above the 370 GB floor instead of the 600 GB all-local floor, and no Tari chain to sync. - Minimal / reuse-an-existing-node: point the stack at nodes you already run (
monero.modeandtari.mode: remote); the host then needs only enough for P2Pool, the proxy, dashboard, and Tor — an 8 GiB chain-free disk budget, and no node RAM at all.
Sizing the miners that connect to this host is separate; their CPU determines hashrate. See RigForge's Hardware Requirements.
- Getting Started — prerequisites and first-run setup.
- Configuration — pruning, data directories, remote nodes, and
tari.mem_limit. - Connecting Miners — connecting rigs to this host.
- RigForge — provision a tuned miner; miner hardware specs.
- Architecture — the services and how they fit together.