Restart your server on a schedule, without losing anything
Killing a game server on a timer is easy and costs you data. The correct shape is warn, warn, save, then stop — and every game spells those three verbs differently. Pick yours and take the script.
Pick your game
When should it restart?
Use {{minutes}} where the countdown number should go.
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
Shifted 15 minutes earlier than your chosen time, so the restart itself lands on it rather than 15 minutes after.
45 3 * * * /opt/restart-minecraft.sh
The script it runs
Save as /opt/restart-minecraft.sh and make it executable. It assumes rcon-cli is on the path and reads the password from the environment rather than embedding it.
#!/usr/bin/env bash
set -euo pipefail
# Scheduled restart for Minecraft.
# Generated by spawnly.net/tools/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 || trueCron uses the server’s timezone, not yours. Check it with timedatectl before assuming 04:00 means 04:00 where you are — a container in UTC and an admin in Europe are two hours apart in summer and one in winter.
Why the order matters
A restart that skips the save relies on the game saving as it shuts down, and several of the games here do not do that reliably. ARK in particular is notorious for it. Sending an explicit save and waiting for it to return before sending the stop costs a few seconds and removes an entire category of "we lost a day" incident. Sending the stop first and hoping is how people find out which category their game is in.
The cron line runs early on purpose
If you want the server back up at 04:00 and you warn players for fifteen minutes first, the job has to start at 03:45. Almost every guide on this subject schedules the job at the target time and quietly restarts fifteen minutes late. The expression generated above is shifted for you, and it wraps correctly across midnight — a job that would start at 23:50 for a 00:05 restart is written as such rather than as a negative hour.
Keep the password out of the script
The generated script reads the console password from the environment rather than containing it. That is not ceremony: a script with a password in it gets copied into a repository, pasted into a support thread, and included in a backup that goes somewhere else. Put the value in a file only root can read, or in your service unit, and keep the script itself boring enough to share.
Games covered
This list is deliberately shorter than our game catalogue. A restart script built on a console command we were not sure about would fail at four in the morning and take the save with it, so a game appears here only when its commands are known rather than assumed.