Run part of the network yourself.
Every node makes the network a little more decentralized. This page walks through the whole loop — why it matters, what to expect, how to install, and how to keep it running. You don't have to be an expert; you do need a server you can keep online.
Reality check:the install script asks operators to acknowledge that the network has not released a token and running a node currently doesn't earn tokens. Future incentive chatter is not a promise. Don't treat this as guaranteed rewards.
It's the most direct way to make the network real.
A decentralized network is decentralized only if many independent people run a piece of it. Today, that piece is you.
More nodes = more independence
Every additional operator means the network depends a little less on any single party staying online or staying friendly. That's the whole point.
Learn the protocol from the inside
Reading the docs is one thing. Watching catch-up logs scroll, querying /v1/info, debugging your own peer connectivity — that's where the protocol becomes real.
Be ready as it grows
Operators who've been running for a while will have set up monitoring, upgrade habits, and a sense of what normal looks like. That's an accumulated skill — start now and you'll be ahead later.
Cost, time, and effort, in concrete numbers.
No magic, no hand-waving. Here's roughly what a beginner-grade node costs and how much attention it needs.
Monthly cost
A 4 vCPU / 16 GB VPS plus 1.5 TB block storage runs roughly $80–$110/month at common cloud providers. Spare home hardware can be free, with the trade-offs noted in Provision.
Initial sync
Catch-up from snapshots usually takes a few hours over a healthy connection. The HTTP endpoint may refuse connections during the first stretch — that's normal.
Bandwidth
Plan for low-hundreds of GB transferred during initial sync, then steady ongoing peer traffic. A standard cloud monthly transfer allowance is fine.
Ongoing effort
Once it's synced: glance at logs and disk a couple of times a week. Run an upgrade every few weeks when releases ship. Total: minutes, not hours.
Numbers are rough — your real cost depends on the provider and chain growth over time. They're here so you can plan, not to lock you into anyone's pricing.
Pick a machine that can stay online.
An early node operator just needs a stable VPS. Home installs can work, but NAT, sleep modes, dynamic IPs, and port forwarding add a lot of moving parts — go that route only if you're comfortable troubleshooting them.
Cloud / VPS path (recommended)
- Ubuntu 24.04 LTS x64
- 4 vCPU / 16 GB RAM minimum
- 1.5 TB block storage minimum (1.6 TB gives breathing room)
- Public IPv4 address
- Cloud Firewall: SSH restricted, P2P / API ports open
Shared CPU works if budget matters. Dedicated CPU is more reliable for long-running sync, but costs more.
Home / local path
- Keep the machine awake — no laptops closing mid-sync.
- Forward required ports from the router to the host.
- Use wired ethernet if possible.
- Expect Docker Desktop / WSL weirdness on consumer machines.
- Dynamic IP changes will break peer reachability.
Great for learning. Less great if you want a reliable public-facing node.
What you'll actually need.
A node holds its own copy of the network's data and stays in sync with peers. That means real disk, real bandwidth, and a few open ports.
Machine
- 16 GB RAM
- 4 CPU cores or vCPUs
- 1.5 TB free storage
- Public IP address
- Ports 3381-3383 exposed on TCP and UDP
Ports
- 3381/tcp HTTP
- 3382/udp gossip
- 3383/tcp gRPC
Catch-up
A new node downloads historical snapshots, then syncs until max heights rise and block delay approaches zero.
Three steps, in order.
Run these from the target server. Verify resources first, then install, then watch catch-up. If you attached a large volume, make sure ~/hypersnap resolves onto that volume before bootstrapping.
- 1
Preflight the server
Confirm OS, CPU, RAM, disk, and mount state. If disk is tiny here, stop and fix storage first.
Preflightlsb_release -a nproc free -h lsblk -f df -h ip -brief addr - 2
Install via Hypersnap bootstrap
The script installs dependencies, writes ~/hypersnap/hypersnap.sh, fetches Compose/config assets, and starts the managed Docker Compose flow.
Bootstrapmkdir -p ~/hypersnap cd ~/hypersnap curl -sSL https://raw.githubusercontent.com/farcasterorg/hypersnap/refs/heads/main/scripts/hypersnap-bootstrap.sh | bashYou'll be asked to acknowledge there are no current token rewards. That prompt is expected. The network has not yet released a token. Running a node at this time will not earn tokens. - 3
Watch catch-up
Initial snapshot catch-up can take a while. The local health endpoint may refuse connections until enough bootstrap state exists.
Watch logs + healthcd ~/hypersnap ./hypersnap.sh logs # In another terminal: curl -s http://127.0.0.1:3381/v1/info | jq .
A short post-install checklist.
Bootstrap finishes long before catch-up does. Use this checklist a few hours after starting to confirm the node is genuinely healthy and not just running.
Three things to check
- Container is up:
docker compose psshowshypersnapwith statusrunning, notrestarting. - /v1/info responds: on the host,
curl http://127.0.0.1:3381/v1/inforeturns JSON (not Connection refused). - blockDelay is decreasing: check it twice, fifteen minutes apart. The number should go down. If it's flat, something is blocking peer traffic.
Healthy steady-state is roughly blockDelay under 20. Anything between 20 and a few thousand means catching up; bigger numbers mean either a fresh install or something blocking the catch-up.
Quick health snapshot
cd ~/hypersnap
docker compose ps
curl -s http://127.0.0.1:3381/v1/info | jq '{version, peer_id, shardInfos: [.shardInfos[] | {shardId, maxHeight, blockDelay}]}'Open the right ports — not the whole castle.
Cloud firewall (recommended)
- TCP 22 from your IP or Tailscale only
- TCP 3381–3383 from all IPv4/IPv6 (if running a public node)
- UDP 3381–3383 from all IPv4/IPv6 (if running a public node)
- Outbound: allow all
What Compose actually publishes
3381:3381/tcp3382:3382/udp3383:3383/tcp
The README says ports 3381–3383 on TCP and UDP. The wider firewall rule is safer while upstream packaging is still moving.
Day-to-day commands.
The bundled script wraps the most common tasks so you don't have to memorize flags.
cd ~/hypersnap && ./hypersnap.sh upgradecd ~/hypersnap && ./hypersnap.sh logscd ~/hypersnap && ./hypersnap.sh downcurl http://localhost:3381/v1/info | jq .curl -sSL https://raw.githubusercontent.com/farcasterorg/hypersnap/refs/heads/main/scripts/hypersnap-bootstrap.sh | bash -s nightlyStay on a recent build, without surprises.
The protocol moves; nodes need to follow. The bundled script keeps upgrades simple.
Use the stable channel
Stable is what most operators should run. It's released, versioned, and won't pull untested code. Nightly tracks the latest commit and is for contributors testing changes — not for a production node.
One-command upgrade
The bundled script pulls the new image, restarts the container, and keeps the same volumes (so your synced state survives the upgrade).
Verify after
Confirm the new version landed and the node still answers /v1/info. If it doesn't, check logs immediately — don't leave a partially-upgraded node running overnight.
cd ~/hypersnap
./hypersnap.sh upgrade
docker compose ps
curl -s http://127.0.0.1:3381/v1/info | jq '.version'If an upgrade introduces a hard schema change, the node may need to re-sync from a fresh snapshot. Watch the release notes when bumping a major version.
Lock down the server itself.
The node is one process on a Linux server, and the server is the bigger attack surface. These are the defaults you'd want anywhere — they take ten minutes.
SSH: keys only, no root
Disable password login. Disable direct root SSH. Use a key-only login for a sudo-capable user.
# 1. Generate a key locally if you don't have one (run on your laptop)
ssh-keygen -t ed25519 -C "hypersnap-operator"
# 2. Copy it to the server
ssh-copy-id <user>@<server-ip>
# 3. On the server, disable password + root SSH
sudo sed -i \
-e 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' \
-e 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' \
/etc/ssh/sshd_config
sudo systemctl reload sshAutomatic security updates
Enable unattended security updates so OS patches land without you manually running apt upgrade on schedule.
sudo apt update
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgradesWorth considering
- Tailscale or WireGuard for SSH. Then your cloud firewall can lock TCP 22 to that private network only — even if a key leaks, the surface is much smaller.
- fail2ban as a cheap layer against brute-force scanners hitting public services.
- Off-server log shipping if you care about post-mortem detail. Even a daily
journalctlsnapshot to a second host is better than nothing.
Install the helper once, then stop debugging by screenshot.
The open-source hypersnap command wraps the common operator checks into copy-pasteable diagnostics and sanitized support reports. It does not replace upstream; it makes upstream easier to run.
One command to diagnose
Install the helper from this site, then run the doctor whenever a node is acting weird. The report checks Docker, Compose, containers, ports, disk, memory, logs, and the local info endpoint.
curl -fsSL https://hypersnap.org/install.sh | bashShare a sanitized report
hypersnap share writes a local report designed for GitHub issues, Discord, or Farcaster support threads. Review it before posting publicly.
hypersnap doctor
hypersnap shareAsk for terminal output, not screenshots.
If the helper is not installed yet, this read-only fallback captures the state that explains 90% of failed installs: containers, logs, disk, ports, and the health endpoint.
cd ~/hypersnap 2>/dev/null || true
printf '\n== host ==\n'
hostnamectl 2>/dev/null || uname -a
printf '\n== resources ==\n'
nproc; free -h; df -h
printf '\n== docker containers ==\n'
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}' 2>&1
printf '\n== compose ps ==\n'
(docker compose ps || docker-compose ps) 2>&1
printf '\n== ports ==\n'
ss -tulpen | grep -E '3381|3382|3383' || true
printf '\n== info endpoint ==\n'
curl -fsS --connect-timeout 5 http://127.0.0.1:3381/v1/info 2>&1 || true
printf '\n== recent logs ==\n'
(docker compose logs --tail 120 hypersnap || docker-compose logs --tail 120 hypersnap) 2>&1Paste /v1/info, get a sanity check
Quick local classifier for the node info JSON. Nothing is uploaded — it runs in your browser.
Paste JSON from /v1/info above and hit Analyze. Nothing leaves your browser.
Common failures, with what they actually mean.
Container exits with code 1 after a manual docker run
Most common cause: starting the image without the generated config.toml or the right volume mounts. Stop creating new failed containers, read logs from the latest one, and switch to the bootstrap / Compose flow.
docker ps is empty
No running container. Run docker ps -a to see failed/stopped containers, then read logs from the newest failed one.
/v1/info refuses connection during the first sync
Often normal during snapshot bootstrap. Check the logs for snapshot chunk progress before declaring the node dead. The endpoint usually wakes up within the first hour.
Ports look closed from outside
Separate the layers: cloud firewall, host firewall (UFW), Docker port mapping, app readiness. If packets reach the server but the app returns RST, it's the app, not the firewall. sudo ss -tulpen | grep 3381 on the host tells you whether the process is actually listening.
Disk hits 100% during snapshot import
Don't blindly delete snapshot artifacts. Run df -h and du -xhd1 ~/hypersnap first. Prefer expanding storage over cleanup unless you can prove a staging directory is stale and unused.
blockDelay isn't going down
A few possibilities. Check them in order:
- Is the node actually receiving peer traffic?
docker compose logsshould mention peers / gossip. - Are the firewall rules letting peers in on UDP 3382?
- Is the server's clock synced? Drift breaks block validation.
timedatectlshould report active NTP. - Is disk full or near full?
df -h.
Node restarts in a loop
Read the logs from the latest exit: docker compose logs --tail 200 hypersnap. Look for the first error before the crash, not the last line. The most common causes are missing volumes, corrupted state from a hard kill mid-write, or a release version mismatch after a partial upgrade — try ./hypersnap.sh down && ./hypersnap.sh upgrade.
Out of memory or OOM-kills
Hypersnap wants 16 GB of real RAM. If your VPS swap is doing the heavy lifting, sync will crawl and the kernel may OOM-kill the container. Check dmesg | grep -i kill and free -h. If you're close to the limit, resize the VPS rather than tuning Docker memory limits.
Two messages worth keeping in your clipboard.
When someone you know is stuck, send terminal output — not screenshots. These ask for the right thing and save a round-trip.
Install message
Please paste terminal output, not screenshots.
If this is a fresh Hypersnap install, use the bootstrap flow — not raw `docker run`:
mkdir -p ~/hypersnap
cd ~/hypersnap
curl -sSL https://raw.githubusercontent.com/farcasterorg/hypersnap/refs/heads/main/scripts/hypersnap-bootstrap.sh | bash
It will ask you to acknowledge there are no current token rewards. That prompt is expected.Debug message
Please run this and paste the full text output:
cd ~/hypersnap 2>/dev/null || true
docker ps -a
(docker compose ps || docker-compose ps) 2>&1
(docker compose logs --tail 120 hypersnap || docker-compose logs --tail 120 hypersnap) 2>&1
df -h
curl -s http://127.0.0.1:3381/v1/info || truePlain-English definitions for the words above.
If you're new to running infrastructure, here's what a few of these terms actually mean.
- Bootstrap
- The one-command install that sets up Docker Compose, generates config, and starts the node. The right entry point for new operators.
- Snapshot
- A pre-baked chunk of historical chain data the node downloads on first start so it doesn't have to replay everything from genesis.
- Sync / catch-up
- The phase where the node imports the snapshot and then follows the latest peer activity until it's current. Usually a couple of hours on a fresh install.
- blockDelay
- How far behind the live tip the node is, in blocks. Closer to zero = closer to synced. Healthy steady-state is roughly under 20.
- Shard
- A horizontal partition of the network's data. Hypersnap runs across multiple shards; the node tracks them all.
- Peer / gossip
- Other nodes your node talks to. They share new messages over a gossip protocol on UDP — that's why UDP 3382 needs to be open.
- FID
- Farcaster ID. The numeric account identifier that owns posts, follows, and signed messages.
- Compose
- Docker Compose, the multi-container orchestrator. The bootstrap script generates a docker-compose.yml that wraps the node, its config, and its persistent volumes.
- RocksDB
- The embedded key-value store the node uses for local state. It lives under ~/hypersnap and is the main reason you need lots of disk.
- Stable / nightly channel
- Stable is the released, tested build. Nightly is the latest commit on main. Run stable in production; use nightly only if you're testing.
Grounded links and credit.
Most of the operator content here is adapted from upstream. Check these before betting time or money.
Big chunks of this guide are adapted from Arca's Hypersnap Node Starter Kit, an operator-friendly wrapper around the upstream bootstrap flow. Thanks to Arca / Cad for the field notes.
This page wraps upstream — it doesn't replace it. Upstream docs are still moving fast and mix Snapchain / Hypersnap language. When in doubt, run the linked source.
Still stuck?
Open an issue on the upstream repo with the diagnostic output above pasted in — every issue is public, and the more concrete output you share the faster someone can help.