Scheduled server restarts that do not lose progress
Any timer can kill a game server; doing it that way loses data. A safe restart warns players, warns again, saves, and only then stops — and each game has its own words for those steps. Choose your game and copy the script.
Pick your game
When should it restart?
Put {{minutes}} wherever the number of minutes left should appear.
What happens, in order
- Job startsWarn
say Server restarting in 15 min - 10 min beforeWarn
say Server restarting in 10 min - 5 min beforeWarn
say Server restarting in 5 min - 1 min beforeWarn
say Server restarting in 1 min - Restart timeSave
save-all - Restart timeStop
stop
stop flushes the world to disk on its way out, so the explicit save-all is belt and braces rather than strictly required. Keep it anyway — it costs nothing and it means the save has already happened if the shutdown hangs.
The crontab line
Moved 15 minutes ahead of the time you picked, so the restart happens at that time instead of 15 minutes later.
45 3 * * * /opt/restart-minecraft.sh
The script it runs
Save it as /opt/restart-minecraft.sh and mark it executable. It expects rcon-cli on the path and takes the password from an environment variable instead of storing it in the file.
#!/usr/bin/env bash
set -euo pipefail
# Scheduled restart for Minecraft.
# Generated by spawnbench.com/restart-scheduler
# The password stays out of this file. Put it in the environment, or in a
# file only root can read, and export it before this script runs.
RCON_HOST="${RCON_HOST:-127.0.0.1}"
RCON_PORT="${RCON_PORT:-25575}"
: "${RCON_PASSWORD:?set RCON_PASSWORD before running}"
send() {
rcon-cli --host "$RCON_HOST" --port "$RCON_PORT" --password "$RCON_PASSWORD" "$1"
}
# 15 minute warning
send 'say Server restarting in 15 min'
sleep 300
# 10 minute warning
send 'say Server restarting in 10 min'
sleep 300
# 5 minute warning
send 'say Server restarting in 5 min'
sleep 240
# 1 minute warning
send 'say Server restarting in 1 min'
sleep 60
# Flush the world to disk
send 'save-all'
sleep 10
# Shut down cleanly
send 'stop'
# Give the process time to finish writing before anything restarts it.
sleep 30
systemctl start minecraft 2>/dev/null || trueHeads up: cron follows the server clock, not your local time. Check with timedatectl first. A container set to UTC and an admin living in Europe differ by two hours in summer and by one in winter, so 04:00 may not be the 04:00 you had in mind.
Advertisement
Why the sequence matters
Skip the save and you are trusting the game to save on the way down — and several games here cannot be trusted with that. ARK is the best-known offender. An explicit save, followed by waiting for it to finish before you send the stop, adds a few seconds and eliminates a whole class of "we lost a day" disasters. Stopping first and hoping for the best is how people learn which class their game falls into.
Advertisement
Why the cron job starts early
Want the server back at 04:00 after a fifteen-minute warning? Then the job must begin at 03:45. Most guides schedule it at the target time instead, so every restart quietly lands fifteen minutes late. The expression above is already moved back, and it handles midnight properly — a 00:05 restart that needs to start at 23:50 is written that way, not as a negative hour.
Do not put the password in the script
The script takes the console password from the environment instead of storing it. This is not fussiness: scripts with passwords inside end up committed to repositories, pasted into help forums and swept into backups stored somewhere else. Keep the value in a root-only file or your service unit, and keep the script dull enough that you could share it with anyone.
Supported games
You will notice this list is shorter than the site's other game lists. That is intentional: a script relying on a console command we had only assumed would break in the small hours and could corrupt the save, so games are added here once their commands have been checked.