Monad

Snapshots

Snapshots provided by EmberStake for Monad

Monad Node Snapshots

We snapshot our Monad nodes three times a day and keep the last 9, so you can always pick one from roughly the past three days. All snapshots are uploaded to Hetzner Object Storage.

Snapshots are taken with monad-cli --dump-binary-snapshot against a finalized block, without stopping the node, so they are a consistent point-in-time export of TrieDB rather than a copy of a data directory.

Node snapshots for Monad Mainnet

SHA256Link

No snapshots available.

Node snapshots for Monad Testnet

SHA256Link

No snapshots available.

Restoring

Monad keeps execution state in TrieDB, on a raw block device with no filesystem — there is no data directory to swap out. Our bucket mirrors the layout of Monad's official snapshot bucket, so the official restore script works against ours with only the host substituted.

Back up your validator identity before you start.id-secp, id-bls and .env cannot be regenerated — losing them loses the validator. Never run two nodes with the same identity at the same time.

Run everything as root. Replace mainnet with testnet throughout for testnet.

1. Stop the node and back up identity

systemctl stop monad-bft monad-execution monad-rpc

mkdir -p /root/monad-backup
cp -a /home/monad/.env                       /root/monad-backup/ 2>/dev/null || true
cp -a /home/monad/monad-bft/config/node.toml /root/monad-backup/ 2>/dev/null || true
cp -a /home/monad/monad-bft/config/id-secp   /root/monad-backup/ 2>/dev/null || true
cp -a /home/monad/monad-bft/config/id-bls    /root/monad-backup/ 2>/dev/null || true
ls -l /root/monad-backup

Confirm the files are there before continuing.

2. Reset the workspace

apt update && apt install -y aria2 jq
bash /opt/monad/scripts/reset-workspace.sh

This wipes local state. It is the point of no return.

3. Restore from our bucket

This is Monad's own restore-from-snapshot.sh, with the snapshot host pointed at us. It re-creates TrieDB in the correct MIP-8 mode, downloads the newest snapshot, verifies its checksum, imports it, and handles the secondary timeline when required.

curl -fsSL https://bucket.monadinfra.com/scripts/mainnet/restore-from-snapshot.sh \
  | sed 's|https://bucket.monadinfra.com/snapshots|https://hel1.your-objectstorage.com/ember-public/snapshots|' \
  | bash
Because the script is fetched fresh each time, you always get Monad's current logic — only the download host changes. Drop the | bash to read what will run first. To restore from Monad's own bucket instead, run it without the sed.

4. Refresh forkpoint and validator set

On monad-bft v0.12.1+ this is optional if you have REMOTE_FORKPOINT_URL / REMOTE_VALIDATORS_URL configured — the node fetches both on start. Otherwise it is required, or the node will not rejoin correctly.

unset REMOTE_VALIDATORS_URL REMOTE_FORKPOINT_URL
MF_BUCKET=https://bucket.monadinfra.com
VALIDATORS_FILE=/home/monad/monad-bft/config/validators/validators.toml

curl -fsSL "$MF_BUCKET/scripts/mainnet/download-forkpoint.sh" -o /tmp/download-forkpoint.sh
bash /tmp/download-forkpoint.sh
curl -fsSL "$MF_BUCKET/validators/mainnet/validators.toml" -o "$VALIDATORS_FILE"
chown monad:monad "$VALIDATORS_FILE"

5. Start and verify

chown -R monad:monad /home/monad/
systemctl start monad-bft monad-execution monad-rpc
journalctl -u monad-bft -f -o cat
curl -s http://localhost:8080/ -X POST -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'

Expect "result":"0x8f" on mainnet (143) or "result":"0x279f" on testnet (10143).


Restoring a specific snapshot

The script above always takes the newest snapshot, which is what you normally want. To use an older one from the table, do steps 1 and 2 as above, then substitute step 3:

SNAPSHOT=<link-from-the-table>
BLOCK=<block-height-from-the-table>
SHA=<sha256-from-the-table>
NETWORK=mainnet

DEST=/home/monad/monad-bft/snapshots
mkdir -p "$DEST" && cd "$DEST"
df -BG "$DEST"        # want ~100GB free

# TrieDB layout depends on whether the MIP-8 hardfork has activated for this network.
MIP8=$(curl -fsSL https://docs.monad.xyz/networks.json \
  | jq -r --arg n "$NETWORK" '.[$n].mip8.hardfork_timestamp // empty')
if [ -n "$MIP8" ] && [ "$(date +%s)" -ge "$MIP8" ]; then MODE=page; else MODE=pre; fi

/usr/local/bin/monad-mpt --storage /dev/triedb --truncate --yes
if [ "$MODE" = page ]; then
  /usr/local/bin/monad-mpt --storage /dev/triedb --create-empty --yes --state-machine monad
  SECONDARY=no
else
  /usr/local/bin/monad-mpt --storage /dev/triedb --create
  /usr/local/bin/monad-mpt --storage /dev/triedb --activate-secondary --state-machine monad \
    && SECONDARY=yes || SECONDARY=no
fi

aria2c -x 8 -s 8 --continue=true "$SNAPSHOT"
FILE=$(basename "$SNAPSHOT")
echo "$SHA  $FILE" | sha256sum -c -      # must print OK

tar -I zstd -xf "$FILE" -C "$DEST"
/usr/local/bin/monad-cli --db /dev/triedb --version "$BLOCK" --load-binary-snapshot "$DEST"
[ "$SECONDARY" = yes ] && /usr/local/bin/monad-cli --db /dev/triedb --version "$BLOCK" \
  --load-binary-snapshot "$DEST" --secondary

Then continue with steps 4 and 5. Each snapshot also has a .checksum file next to it in the bucket, so sha256sum -c <name>.checksum works instead of pasting the hash.

MIP-8 activated on testnet 2026-08-12 and on mainnet 2026-09-02 14:30 UTC. Flag spelling changed in monad-cli v0.16.0 — hyphens (--load-binary-snapshot); older scripts use underscores. Check monad-cli --help if your binary rejects one form.

Monad's official hard reset guide, which lists the Monad Foundation and Category Labs snapshot buckets.