To host a Minecraft Java server on a VPS, install the Java version your Minecraft release needs (Java 25 for the 26.x releases, Java 21 for 1.21.x), give the JVM 2–4 GB for a small world, open TCP port 25565, and run the server as its own user under systemd so it survives a crash and a reboot. This guide sets all of that up on Debian or Ubuntu, with the Rocky and Alma equivalents alongside, and ends with backups and a clean shutdown that actually saves the world.
One technical fact shapes the hardware choice: Minecraft’s main game loop — the “tick” that moves mobs, grows crops and runs redstone — is largely single-threaded. A server lags when one core cannot finish a tick in 50 ms, and adding more cores does not help that. Per-core speed matters more than core count, which is why a few fast cores beat many slow ones for a game server.
How much RAM and CPU does a Minecraft server need?
Treat these as starting ranges, not promises — the real figure depends on your view distance, player count and especially plugins and mods, and the only honest number is the one you measure on your own world:
- Small vanilla server, a handful of players: 2–4 GB of RAM and two fast cores is a sensible start.
- Plugins (Paper/Purpur) or a modpack: more, often 6–8 GB and up. Modded servers are the memory-hungry case; a big pack can want far more than a vanilla world of the same player count.
- Leave headroom. Your
-Xmxmust be smaller than the machine’s RAM — the OS, backups and the JVM’s own off-heap memory all need room. On a 4 GB box, do not hand Java more than about 3 GB.
If ticks fall behind, the server prints Can’t keep up!. That is a CPU or an I/O problem far more often than a RAM one — see VPS high CPU usage for finding which.
How do I install Java and fix java: command not found?
java: command not found simply means no Java runtime is installed yet — a server image never ships one. The version you need depends on your Minecraft version, and that moved recently: current Java Edition releases (the 26.x line) require Java 25, while 1.21.x releases run on Java 21 and older packs may need 17. Minecraft refuses to start on a Java older than it wants, so match them. Check the requirement for your exact version on the official download page, then install a headless runtime — no desktop libraries on a server.
sudo apt update
sudo apt install -y openjdk-25-jre-headless # for 1.21.x, use openjdk-21-jre-headless
java -versionDebian 12 (bookworm) only packages Java 17, so for a current server install Java 25 from Adoptium’s Temurin repository with a keyring the modern way:
sudo apt install -y curl ca-certificates gpg
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://packages.adoptium.net/artifactory/api/gpg/key/public \
| sudo gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg
echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] \
https://packages.adoptium.net/artifactory/deb $(. /etc/os-release && echo $VERSION_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update && sudo apt install -y temurin-25-jre
java -version# Java 25 needs a current 9.x point release — check with:
dnf list --available 'java-*-openjdk-headless'
sudo dnf install -y java-25-openjdk-headless # for 1.21.x: java-21-openjdk-headless
java -versionIf several Java versions are installed, sudo update-alternatives --config java (Debian, Ubuntu) or sudo alternatives --config java (Rocky) selects the default. The systemd unit below calls /usr/bin/java, which follows that default. To pin one version regardless of the default, put its full path in ExecStart instead — ls /usr/lib/jvm lists what is installed.
How do I download and start the server?
- 1Create a dedicated user
Never run the server as root. Give it its own unprivileged account and directory:
user and directory sudo useradd --system --create-home --home-dir /opt/minecraft --shell /usr/sbin/nologin minecraft sudo -u minecraft mkdir -p /opt/minecraft/server - 2Download the server jar
Take the
server.jarURL for your version from the official minecraft.net server download page — it changes every release, so copy the current one rather than hardcoding an old link. Work as the service user so every file it creates belongs to it:download sudo -u minecraft bash # a shell as the service user cd /opt/minecraft/server curl -fsSLo server.jar "https://piston-data.mojang.com/.../server.jar" # paste the real URL - 3Accept the EULA and start once
The first run writes config files and then stops, because you have not yet agreed to Mojang’s EULA:
first start (still in the minecraft shell) java -Xms1G -Xmx1G -jar server.jar nogui # it exits with: "You need to agree to the EULA..." sed -i 's/eula=false/eula=true/' eula.txt exit
Setting eula=true records that you accept Mojang’s EULA. Now open server.properties as the service user (sudo -u minecraft nano /opt/minecraft/server/server.properties) and enable RCON, which the service will use for a clean shutdown:
enable-rcon=true
rcon.port=25575
rcon.password=choose-a-long-random-string
# optional but recommended for a private server:
white-list=true
enforce-whitelist=trueHow do I run it as a systemd service?
A systemd unit keeps the server running after you log out, restarts it if it crashes, and starts it on boot. The key is a shutdown that saves the world first — so instead of letting systemd kill the Java process, have it send the server’s own stop command over RCON, which saves every chunk before exiting.
# Debian 12/13, Ubuntu 24.04 — the rcon package provides rconclt
sudo apt install -y rcon
# Rocky, Alma 9 — not packaged; install the same client from PyPI in a venv
sudo dnf install -y python3.11
sudo python3.11 -m venv /opt/rcon && sudo /opt/rcon/bin/pip install rcon
# then use /opt/rcon/bin/rconclt wherever this guide says /usr/bin/rconcltsudo install -d -m 0750 -o minecraft -g minecraft /etc/minecraft
sudo tee /etc/minecraft/rcon.conf >/dev/null <<'EOF'
[mc]
host = 127.0.0.1
port = 25575
passwd = the-same-string-as-server.properties
EOF
sudo chown minecraft:minecraft /etc/minecraft/rcon.conf
sudo chmod 600 /etc/minecraft/rcon.conf[Unit]
Description=Minecraft server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server
# match -Xmx to your plan, leaving headroom for the OS
ExecStart=/usr/bin/java -Xms2G -Xmx3G -jar server.jar nogui
# graceful stop: save and quit, then wait for Java to exit (systemd signals as soon as ExecStop returns)
ExecStop=/bin/sh -c '/usr/bin/rconclt -c /etc/minecraft/rcon.conf mc stop; while kill -0 $MAINPID 2>/dev/null; do sleep 1; done'
# a JVM ended by SIGTERM exits 143; that is a normal stop, not a failure
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
# give the world time to save before systemd gives up
TimeoutStopSec=90
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now minecraft
sudo systemctl status minecraft
# watch the log
sudo journalctl -u minecraft -f
# test that a stop saves the world:
sudo systemctl stop minecraft # the log must show "Saving worlds" before it exitsWhich port does a Minecraft server need?
Java Edition listens on TCP 25565. Open exactly that, and no more:
# ufw (Debian, Ubuntu)
sudo ufw allow 25565/tcp comment 'Minecraft'
# firewalld (Rocky, Alma)
sudo firewall-cmd --permanent --add-port=25565/tcp && sudo firewall-cmd --reloadLeave RCON’s port 25575 closed. The vanilla server binds RCON to every interface unless server-ip is set, so the firewall is what keeps it private — with a default-deny firewall it stays closed as long as you never allow it, and the service reaches it over 127.0.0.1. A full firewall walkthrough, including allowing SSH before you enable the firewall, is in the UFW setup guide. Bedrock Edition is a different server program and listens on UDP 19132; this guide is Java Edition.
How do I back up the world safely?
Back up the world directory on a schedule. Because the server writes to it constantly, flush and pause saves over RCON first, copy, then re-enable — so the archive is consistent:
#!/bin/bash
set -euo pipefail
R="/usr/bin/rconclt -c /etc/minecraft/rcon.conf mc"
DEST=/opt/minecraft/backups
mkdir -p "$DEST"
$R save-off # stop writing to disk
trap '$R save-on' EXIT # always resume saving, even if tar fails
$R save-all flush # flush everything to disk now
tar -czf "$DEST/world-$(date +%F-%H%M).tar.gz" -C /opt/minecraft/server world
# keep the last 14 archives
ls -1t "$DEST"/world-*.tar.gz | tail -n +15 | xargs -r rm --sudo chown minecraft:minecraft /opt/minecraft/backup.sh
sudo chmod 750 /opt/minecraft/backup.sh
# append to the user's crontab instead of replacing it
(sudo crontab -u minecraft -l 2>/dev/null; echo "30 4 * * * /opt/minecraft/backup.sh") \
| sudo crontab -u minecraft -A file backup protects you from a corrupt world or a bad command, but it lives on the same disk — copy the archives off the server too (rsync to another machine is enough). Before a big change, such as a Minecraft update or a new plugin set, a snapshot of the whole VPS from your provider’s panel, if it offers one, is the faster roll-back.
Why does the server lag or crash?
- Steady lag / “Can’t keep up”: a tick is taking too long. Lower view and simulation distance, thin out entities and redstone, and if the box is pinned, work through VPS high CPU usage.
- The process just says
Killed: the machine ran out of memory and the kernel killed Java. Lower-Xmx, add RAM, or see why Linux kills your process. - Crashes on start after an update: almost always a Java-version mismatch — the new Minecraft wants a newer Java than you have installed. Re-check the Java section.
Does a Minecraft server need DDoS protection?
For a public server, yes. Game servers draw denial-of-service attacks, often from whoever just lost, and a small VPS cannot filter a flood on its own — that has to happen upstream, at the provider. Check that your host includes it; on VMHeaven, for example, always-on DDoS mitigation sits in front of every server at no extra cost. What you still do yourself is the ordinary hardening — key-only SSH and the rest of the base setup — so the box that runs the game is not itself the soft target.
What hardware does a Minecraft VPS need?
Because the tick is largely single-threaded, choose fast cores over many cores, and enough RAM for the -Xmx you planned plus headroom. Two to four strong vCores cover a small server; extra cores mainly help world generation, plugins that work asynchronously and everything else on the box. Our Hi-CPU KVM line (AMD EPYC 7443) is built for this kind of one-or-two-thread work. Location matters less than people expect: put the server close to most of your players, and see Frankfurt or Amsterdam for how to measure the route from your own players rather than guess.
A plain VPS is more work than a one-click Minecraft hosting panel, and that is the honest trade: the panel is easier, while a VPS gives you full root, any Java version, any plugin loader, and a box you can use for anything else too. If you are comfortable on the command line, the setup above is a one-time half hour.
Running a different game? The gaming VPS page covers Palworld, Valheim, Enshrouded, Satisfactory, Rust, 7 Days to Die, Project Zomboid, FiveM and ARK: Survival Ascended: what each developer publishes for its server, where it publishes anything, next to the smallest plan on each line with room to start, and a link to each game’s own guide once it is out.
Frequently asked
How much RAM does a Minecraft server need?
For a small vanilla world with a few players, 2–4 GB is a sensible start; plugin servers (Paper/Purpur) and modpacks need more, often 6–8 GB and up. Always set the JVM's -Xmx below the machine's total RAM so the OS and the JVM's own off-heap memory have room — on a 4 GB box, give Java about 3 GB, not all of it. The real figure depends on view distance, player count and especially mods, so measure it on your own world.
Which Java version do I need?
Match it to your Minecraft version. Current Java Edition releases (the 26.x line) require Java 25; 1.21.x releases run on Java 21, and older packs may need 17. Minecraft refuses to start on a Java older than it expects, so check your version's requirement on the official download page and install a headless runtime of that version.
Why does my server say 'java: command not found'?
No Java runtime is installed — a server image never ships one. Install a headless runtime that matches your Minecraft version: on Ubuntu 24.04 and Debian 13 'openjdk-25-jre-headless'; on Debian 12, which only packages Java 17, Adoptium's Temurin repository provides temurin-25-jre; on a current Rocky or Alma 9 'java-25-openjdk-headless'. Then 'java -version' should print it.
VPS or a Minecraft hosting panel?
A one-click Minecraft host is easier and the honest reason to pick it is convenience. A VPS is a little more setup but gives you full root, any Java version, any plugin or mod loader, backups you control, and a machine you can use for other things too. If you are comfortable on the command line, the VPS setup is a one-time job of about half an hour.