Guides

Minecraft Server Backups That Actually Restore (2026 Guide)

· · 2 views

The night your host's disk dies is the worst possible time to learn that your backups don't restore. And most don't: the archive was written while the server was still flushing region files, so half the .mca files inside are truncated. The world loads, but chunks come back as freshly generated terrain — or the server crashes on boot with Failed to read chunk. You had backups for eight months. You had usable backups for zero.

This guide builds a backup setup that survives the only test that matters: an actual restore. The save-off trick that prevents corruption, a cron script for VPS setups, offsite copies with restic, a plugin route for shared hosting without SSH, and the 15-minute monthly drill that proves the whole chain. Everything here applies whether you're still on Paper 1.21.x or the new 26.x releases.

TL;DR — Never copy a running world without save-off + save-all flush first. Back up the worlds, plugins/, and your configs; skip logs, caches, and map tiles. Ship an encrypted copy offsite (from $6/TB/month) and restore-test monthly. For the rest of your hosting bill, see what a server really costs in 2026.

Why most Minecraft server backups are corrupt

A running server holds loaded chunks in memory and writes them to region files (world/region/*.mca) on its own schedule — an autosave roughly every five minutes by default, plus continuous writes as chunks unload. If your backup job copies a region file mid-write, you archive a file that's internally inconsistent. tar won't complain. The upload won't complain. You find out at restore time, when chunks regenerate as empty terrain or the server refuses to start.

The fix is two console commands before the copy and one after:

save-off        # stop the server writing world files
save-all flush  # force everything in memory onto disk, now
# ...copy the files here...
save-on         # resume normal saving

save-off doesn't pause the game — players keep playing with zero lag. The server just holds world writes in memory until save-on. Every method below is built around this window; any method that isn't (including "I just zip the folder in FileZilla while it runs") produces archives you can't trust.

What to back up — and what to skip

Copy these, always:

  • world/, world_nether/, world_the_end/ — Paper and Spigot split dimensions into three folders; vanilla keeps everything inside world/. Player inventories ride along in world/playerdata/.
  • plugins/ — not just the JARs, the data: your LuckPerms database, Essentials homes, quest progress, and plugins/Votifier/rsa/. Lose those keys and you're regenerating and re-registering on every toplist (see our NuVotifier setup guide).
  • server.properties, bukkit.yml, spigot.yml, and the config/ folder (Paper's own configs live there)
  • whitelist.json, ops.json, banned-players.json, banned-ips.json

Skip these — large, regenerable, or both:

  • logs/, crash-reports/, cache/, libraries/, versions/
  • Dynmap or BlueMap tile folders — often 10–50 GB of renders the plugin will happily redraw
  • The server JAR itself. Instead, write the exact build into a VERSION.txt ("Paper 1.21.11, build 88") so restore day starts with a clean re-download — our server JARs page has every version.

One trap that bites later: if LuckPerms, CoreProtect, or your economy runs on MySQL instead of flat files, none of that data is in the world folder. Add one line to your backup: mysqldump -u mc -p minecraft | gzip > db_backup.sql.gz. And decide consciously about CoreProtect — its database routinely passes 20 GB and can dwarf the world itself. Seven days of block-log history is worth storing; six months of it is a storage bill.

Method 1: automatic backups with cron (VPS and dedicated)

This assumes your server runs in a screen session named mc — the most common self-hosted setup. Save as /home/mc/mc-backup.sh:

#!/bin/bash
SERVER_DIR="/home/mc/server"
BACKUP_DIR="/home/mc/backups"
STAMP=$(date +%F_%H-%M)

cmd() { screen -S mc -p 0 -X stuff "$1$(printf '\r')"; }

# re-enable saving even if this script dies halfway
trap 'cmd "save-on"' EXIT

cmd "save-off"
cmd "save-all flush"
sleep 15   # let the flush hit disk; use 60+ for 10 GB+ worlds

mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/mc_$STAMP.tar.gz" \
  -C "$SERVER_DIR" \
  world world_nether world_the_end plugins config \
  server.properties bukkit.yml spigot.yml \
  whitelist.json ops.json banned-players.json banned-ips.json

# keep 7 days locally; offsite storage handles longer history
find "$BACKUP_DIR" -name "mc_*.tar.gz" -mtime +7 -delete

Make it executable (chmod +x mc-backup.sh) and schedule it for your quietest hour:

crontab -e
# daily at 04:30
30 4 * * * /home/mc/mc-backup.sh >> /home/mc/backups/backup.log 2>&1

The line that earns its keep is the trap. Without it, a script that dies between save-off and save-on leaves the server silently not saving — players build for hours, the server restarts, and everything since the crash is gone. With it, save-on fires no matter how the script exits.

Running under systemd instead of screen? Enable RCON in server.properties (enable-rcon=true, set a strong rcon.password) and swap the cmd function for:

cmd() { mcrcon -H 127.0.0.1 -P 25575 -p "your-rcon-password" "$1"; }

Offsite backups with restic: the 3-2-1 setup

A tarball on the same disk as the server protects you from your own mistakes, not from hardware failure or a host that disappears. The rule worth following is 3-2-1: three copies, two different media, one offsite. For a Minecraft server that means live files, local tarballs, and an encrypted offsite repository.

restic (0.19.1 as of July 2026) is the right tool for the offsite leg: it deduplicates — thirty daily snapshots of a 10 GB world don't cost 300 GB, they cost roughly one world plus whatever changed — encrypts everything by default, and prunes old snapshots by policy. Your distro's package may lag behind; run restic self-update after installing.

# one-time setup
export RESTIC_REPOSITORY="sftp:u123456@u123456.your-storagebox.de:mc-backups"
export RESTIC_PASSWORD="a-long-passphrase-stored-somewhere-safe"
restic init

Then replace (or follow) the tar line in Method 1 — inside the same save-off window — with:

restic backup "$SERVER_DIR" \
  --exclude logs --exclude cache --exclude crash-reports \
  --exclude libraries --exclude versions

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

That forget line is your retention policy as a decision rule: every day for a week, a weekly for a month, a monthly for half a year. It matches how disasters actually get discovered — griefing and dupe damage usually surfaces one to fourteen days after it happened, not the same night.

Two more commands close the gap between "the backup ran" and "the backup is readable". Put restic check --read-data-subset=5% in a weekly cron — it downloads and verifies a random 5% of the repository, catching silent corruption without paying a full restore's bandwidth. For the local tarballs, add gzip -t "$BACKUP_DIR/mc_$STAMP.tar.gz" || echo "BACKUP BROKEN" | mail -s "backup failed" you@example.com to the Method 1 script, so a truncated archive pages you instead of hiding for months.

Where to point the repository, at July 2026 prices:

  • Hetzner Storage Box BX11 — 1 TB for €3.20/month, unlimited traffic, speaks SFTP so the repository URL above works unchanged. The default pick.
  • Backblaze B2 — $6/TB/month ($0.006/GB) with free egress up to 3x your stored volume, so even a full-server restore download costs nothing. Use restic -r b2:your-bucket:mc with your B2 application keys.

Either way, a 10–15 GB survival server with six months of deduplicated history lands well under $1/month — the cheapest line in your entire server budget.

Backups on shared hosting (no SSH, no cron)

On typical shared Minecraft hosting you can't install restic or edit a crontab. You have two levers:

Panel backups. Most hosts run Pterodactyl, and its Backups tab genuinely works — but read the fine print. Slots are usually capped at one to three, and unless your host ships backups to external storage, they live on the same machine as your server. Treat panel backups as "undo a bad plugin update", not as disaster recovery.

DriveBackupV2 (free; 1.8.1 as of early 2026) runs as a plugin, so it works anywhere you can upload a JAR. It triggers a world save, zips your folders on a schedule, and uploads to Google Drive, OneDrive, Dropbox, or any SFTP box — real offsite copies with zero console access:

  1. Drop the JAR into plugins/ and restart.
  2. In plugins/DriveBackupV2/config.yml, set delay: 720 (minutes between backups — twice a day) and keep-count: 14.
  3. Run /drivebackup linkaccount googledrive in-game as op and follow the device-code prompt.

Zipping a big world on shared CPU causes a visible lag spike, so schedule around your dead hours and resist backing up hourly out of paranoia — twice a day plus a panel snapshot before every plugin change covers a small server.

The restore test: 15 minutes a month, non-negotiable

An untested backup is a hope, not a backup. Once a month:

  1. Pull the latest snapshot to your PC or a scratch VPS: restic restore latest --target ./restore-test, or untar the newest tarball.
  2. Add a matching server JAR — same software, same version as production. That's what VERSION.txt was for, and it's one more reason to run maintained software (Paper vs Spigot vs Purpur vs Folia).
  3. Start it — java -Xmx2G -jar paper.jar --nogui — and join via localhost.
  4. Check three things: the spawn area is intact (region files survived), a chest you know is full still has its items (block entities survived), and your rank and permissions work (plugin data survived).

Pass all three and the entire chain — save-off, copy, upload, retention — is proven. Fail, and you found out on a quiet Tuesday afternoon instead of the night the host's RAID died.

Tip: the most common real restore isn't the whole server — it's one player. Inventories live in world/playerdata/<uuid>.dat (map names to UUIDs via usercache.json). Pull just that file from a snapshot and copy it in while the player is offline — restore it while they're online and their in-memory data overwrites your work the moment they log out.

Your world is safe — now put it in front of players

A disaster plan matters most when there are players who'd notice the downtime. If your server isn't listed yet, add it to the toplist — free, five minutes, and it starts collecting votes immediately. Already listed? Point the server status checker at your address after your next restart to confirm players see you online, because a server that's down doesn't just lose players — it slides down the rankings while you sleep.

Tags: minecraft server backup backup and restore restic cron server administration world corruption
More from the blog
How to Fix Minecraft Server Lag: 2026 Optimization Guide
Aug 22, 2026
Most lag advice is cargo-culted. This guide shows you how to tell TPS lag from network lag in 30 seconds with spark, the…
How Much RAM Does a Minecraft Server Need? (2026 Guide)
Aug 22, 2026
The honest answer, with numbers: 4 GB covers most vanilla and Paper servers up to ~20 players, modpacks need 6–10 GB, an…
Minecraft Server Statistics 2026: What 366 Live Servers Reveal
Aug 22, 2026
We analyzed a live snapshot of 366 Minecraft Java servers tracked by our monitoring system. The results: one in three on…