Skip to content
Operators

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.

Why run a node

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.

What to expect

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.

Provision

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.

Requirements

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.

Install

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. 1

    Preflight the server

    Confirm OS, CPU, RAM, disk, and mount state. If disk is tiny here, stop and fix storage first.

    Preflight
    lsb_release -a
    nproc
    free -h
    lsblk -f
    df -h
    ip -brief addr
  2. 2

    Install via Hypersnap bootstrap

    The script installs dependencies, writes ~/hypersnap/hypersnap.sh, fetches Compose/config assets, and starts the managed Docker Compose flow.

    Bootstrap
    mkdir -p ~/hypersnap
    cd ~/hypersnap
    curl -sSL https://raw.githubusercontent.com/farcasterorg/hypersnap/refs/heads/main/scripts/hypersnap-bootstrap.sh | bash
    You'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. 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 + health
    cd ~/hypersnap
    ./hypersnap.sh logs
    # In another terminal:
    curl -s http://127.0.0.1:3381/v1/info | jq .
Confirm it's working

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 ps shows hypersnap with status running, not restarting.
  • /v1/info responds: on the host, curl http://127.0.0.1:3381/v1/info returns 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

One-liner
cd ~/hypersnap
docker compose ps
curl -s http://127.0.0.1:3381/v1/info | jq '{version, peer_id, shardInfos: [.shardInfos[] | {shardId, maxHeight, blockDelay}]}'
Network

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/tcp
  • 3382:3382/udp
  • 3383:3383/tcp

The README says ports 3381–3383 on TCP and UDP. The wider firewall rule is safer while upstream packaging is still moving.

Operations

Day-to-day commands.

The bundled script wraps the most common tasks so you don't have to memorize flags.

Upgrade
cd ~/hypersnap && ./hypersnap.sh upgrade
Logs
cd ~/hypersnap && ./hypersnap.sh logs
Stop
cd ~/hypersnap && ./hypersnap.sh down
Local info
curl http://localhost:3381/v1/info | jq .
Nightly channel
curl -sSL https://raw.githubusercontent.com/farcasterorg/hypersnap/refs/heads/main/scripts/hypersnap-bootstrap.sh | bash -s nightly
Upgrades

Stay 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.

Upgrade and verify
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.

Hardening

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.

SSH hardening
# 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 ssh

Automatic security updates

Enable unattended security updates so OS patches land without you manually running apt upgrade on schedule.

Auto-updates
sudo apt update
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Worth 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 journalctl snapshot to a second host is better than nothing.
Operator toolkit

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.

Install helper
curl -fsSL https://hypersnap.org/install.sh | bash

Share a sanitized report

hypersnap share writes a local report designed for GitHub issues, Discord, or Farcaster support threads. Review it before posting publicly.

Doctor + report
hypersnap doctor
hypersnap share
Diagnostics

Ask 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.

Read-only diagnostic
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>&1

Paste /v1/info, get a sanity check

Quick local classifier for the node info JSON. Nothing is uploaded — it runs in your browser.

Idle

Paste JSON from /v1/info above and hit Analyze. Nothing leaves your browser.

Troubleshooting

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 logs should mention peers / gossip.
  • Are the firewall rules letting peers in on UDP 3382?
  • Is the server's clock synced? Drift breaks block validation. timedatectl should 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.

Helping a friend

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

Send this
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

Send this
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 || true
Glossary

Plain-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.
Sources

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.