Hardware and disk
Snapchain's README asks for 16 GB RAM, 4 vCPUs and 1.5 TB of disk; its getting-started page says 2 TB. What we measured:
| Item | Size | Checked with |
|---|---|---|
| Snapshot, as downloaded | 5,691 chunks in 3 shards | fetch-snapshot output |
| Node database after unpacking | 557 GB | du -sh ~/snapchain/.rocks |
| Database size the node reports | 557,823,184,195 bytes | selfcast info |
The download keeps each shard's chunks until that shard is unpacked, then deletes them. So the most disk it uses is while the second large shard unpacks: the chunks not yet unpacked plus the two large shards already unpacked, about 770 GB. fetch-snapshot refuses to start with less than 800 GB, counting what it has already downloaded (--skip-disk-check overrides it).
The 770 GB peak is worked out from shard sizes (about 470 GB of chunks; 557 GB unpacked), not measured. Snapchain's own download keeps more on disk at once, which is why its docs ask for 1.5 to 2 TB.
Renting a server instead
Look for 4 or more vCPUs, 16 GB of RAM and at least 1 TB of disk (a server's own disk is usually far smaller, so add a block-storage volume). Most providers bill by the hour, so a test that takes two days costs two days. One example, read from Hetzner's price page on 2026-10-21: CPX42, 8 vCPU, 16 GB RAM, 320 GB disk, €0.1122 an hour or €69.99 a month at most, excluding VAT, in its EU locations. The volume is extra; that page gives no price for it. When you are done, delete both the server and the volume.
The snapshot
A new node does not replay Farcaster's history block by block. It starts from a snapshot: a copy of a node's database, published for new nodes to start from and split into chunks of about 90 MB. The one we fetched was dated 2026-10-18.
Snapchain can download the snapshot itself when it first starts, but that download cannot resume. A network gap of about 50 seconds stops the node, and the restart begins again at chunk 1. Worse, if the first shard has already been unpacked, the restart sees a non-empty database, skips the snapshot, and runs on an incomplete copy without saying so. On a home connection the download takes many hours, so selfcast has its own downloader, which can stop and pick up where it left off.
Download
selfcast node fetch-snapshot
0 of 5691 chunks already on disk
[1/5691] shard 1 chunk_0003.bin 35.2 MB/s ETA 7h03m
[2/5691] shard 1 chunk_0002.bin 35.5 MB/s ETA 3h45m
[3/5691] shard 1 chunk_0004.bin 36.7 MB/s ETA 3h09m
…
Ctrl-C stops it. Running it again continues, including chunks that were half done:
selfcast node fetch-snapshot --jobs 8
112 of 5691 chunks already on disk
resuming ~/snapchain/.selfcast-snapshot/shard-1/chunk_0115.bin.part at 11.5 MB
resuming ~/snapchain/.selfcast-snapshot/shard-1/chunk_0114.bin.part at 56.2 MB
…
--jobs is how many chunks download at once; the default is 4. On the test machine 8 was less than 10% faster, because the line, not the server, was the limit.
Download in the background
To close the terminal while it runs, use pause and resume instead. resume starts the download in the background and appends its output to ~/snapchain/selfcast-fetch.log; pause stops it, keeping everything downloaded.
selfcast node resume
selfcast node pause
What resume writes to the log:
=== resume 2026-10-19T11:02:01Z --jobs 4
2649 of 5691 chunks already on disk
resuming ~/snapchain/.selfcast-snapshot/shard-1/chunk_2652.bin.part at 60.0 MB
…
Only one download runs per install directory: a second fetch-snapshot or resume while one is running does not start another.
Unpack
When the last chunk arrives, the download unpacks each shard into the node's database:
[5691/5691] shard 0 chunk_0367.bin 8.1 MB/s ETA 0h00m
unpacking shard 1 (2672 chunks)
unpacking shard 2 (2648 chunks)
unpacking shard 0 (371 chunks)
snapshot ready: 5691 chunks unpacked into ~/snapchain/.rocks
start the node: cd ~/snapchain && ./snapchain.sh up
Every pause leaves the snapshot older by the time you were paused, and the node has to sync that time back once it starts.
Start the node
cd ~/snapchain && ./snapchain.sh up
The node starts from the unpacked database without downloading again. up then follows the node's log; Ctrl-C stops following it and leaves the node running.
Watch it
selfcast node status works in every phase: downloading the snapshot, unpacking, stopped, syncing and ready. It also reports free disk. While the node is behind:
selfcast node status
Syncing (Snapchain 0.14.3): 47h07m behind at most.
shard 0: height 48391469, 23h49m behind
shard 1: height 49002681, 41h55m behind
shard 2: height 48819789, 47h07m behind
Disk: 3165 GB free of 3996 GB.
Snapchain splits the network into shards, each its own chain of blocks. A shard's height is the number of its newest block, and “behind” is how old that block is. The node reports ready once every shard is within a minute of its newest block. Your node's own numbers:
selfcast info
{
"dbStats": {
"approxSize": 557823184195,
"numFidRegistrations": 3355165,
"numMessages": 914246336
},
"nextEngineVersionTimestamp": 0,
"numShards": 2,
"peer_id": "12D3KooWEYXexrGCimknLUiKsEijFohY4HCJxo1vB4joawm8VCvS",
"shardInfos": [
{
"approxSize": 38892955790,
"blockDelay": 85744,
"maxHeight": 48391470,
"mempoolSize": 0,
"numFidRegistrations": 0,
"numMessages": 12668689,
"shardId": 0
},
{
"approxSize": 280148797489,
"blockDelay": 150942,
"maxHeight": 49002681,
"mempoolSize": 4294967295,
"numFidRegistrations": 1677734,
"numMessages": 458613892,
"shardId": 1
},
{
"approxSize": 277674386706,
"blockDelay": 169654,
"maxHeight": 48819790,
"mempoolSize": 4294967295,
"numFidRegistrations": 1677431,
"numMessages": 455632444,
"shardId": 2
}
],
"version": "0.14.3"
}
Shards 1 and 2 hold about 1.68 million accounts each and nearly all the messages; shard 0 holds no accounts, and numShards counts only the two that do. The snapshot has all three. The same data comes straight from Snapchain's API with curl http://localhost:3381/v1/info, unformatted.
Why sync is slow
The test node started 25 to 48 hours behind. What we saw while it caught up:
- While the machine was awake and the node was catching up, it gained about 2 seconds of the network's time per second, in samples of 35 s to 2 min.
- For over two hours, the furthest-behind shard made no net progress, with the container up the whole time. We have not found why.
- CPU and bandwidth were not the limit: over 30 s the node used about 3% CPU and received about 20 KB/s.
Snapchain v0.14.3 syncs through the Malachite library, pinned at commit 13bca14, which asks a peer for one block at a time and waits for the answer before asking for the next (code/crates/sync/src/handle.rs, request_value). From the test machine a peer was about 250 ms away, which fits about 3 blocks per second per shard. Newer Malachite can ask for several blocks at once; no Snapchain release uses it, as of v0.14.3.
Ports, and who can reach your node
| Port | Protocol | Used for |
|---|---|---|
| 3381 | TCP | HTTP API: reads, and submitting messages |
| 3382 | UDP | Gossip with other nodes |
| 3383 | TCP | gRPC API |
Snapchain's compose file publishes these on every network interface. On the test machine that put the HTTP API, including message submission, within reach of anything on the local network. To keep the APIs on your machine and leave only gossip open, add this file next to Snapchain's docker-compose.yml. ./snapchain.sh upgrade replaces docker-compose.yml but leaves this file alone.
services:
snapchain:
environment:
RUST_LOG: "warn,informalsystems_malachitebft_sync=error"
ports: !override
- "127.0.0.1:3381:3381/tcp"
- "3382:3382/udp"
- "127.0.0.1:3383:3383/tcp"
statsd:
ports: !override
- "127.0.0.1:8125:8125/udp"
- "127.0.0.1:8126:8126"
Then restart the node, and once up is showing the log, press Ctrl-C and check:
cd ~/snapchain && ./snapchain.sh down && ./snapchain.sh up
docker port snapchain-snapchain-1
3381/tcp -> 127.0.0.1:3381
3382/udp -> 0.0.0.0:3382
3382/udp -> [::]:3382
3383/tcp -> 127.0.0.1:3383
With this in place, the HTTP API answered on localhost and refused a connection to the machine's LAN address.
Logs
The RUST_LOG line in the file above keeps warnings and errors only. Without it, the sync library logs a “SYNC REQUIRED” warning for every block while the node catches up: about 0.9 MB of log a minute on the test machine, against about 6 KB with it. To read the log:
docker logs --tail 4 snapchain-snapchain-1
2026-10-20T10:06:08.093084Z WARN snapchain::network::gossip: Failed to publish gossip message: InsufficientPeers ("read-node-peers")
2026-10-20T10:06:17.991223Z WARN snapchain::network::gossip: Failed to publish gossip message: InsufficientPeers ("read-node-peers")
…
The log lives with the container and goes when the container is removed: by ./snapchain.sh down, or when it is recreated after a change to its ports.
Sleep, shutdown and logout
With OrbStack set to pause in sleep and the lid closed for 40 minutes, the node wrote nothing, the container did not restart, and on waking it reconnected to peers and caught up at the same rate as before. It came back 40 minutes further behind. A node on a laptop is only syncing while the laptop is awake.
Upgrades
The bootstrap script adds a weekly cron job that upgrades Snapchain, unless ~/snapchain/.env contains SKIP_CRONTAB=true. The quickstart adds it, so upgrades happen by hand. The weekly job also runs docker system prune --volumes -f after each upgrade (the autoupgrade branch of snapchain.sh), which deletes every stopped container and unused volume on the machine, not only Snapchain's. On a server used only for the node that is harmless; on your own computer it is not. To upgrade:
cd ~/snapchain && ./snapchain.sh upgrade
Next: Using the client