Guides

Host a Minecraft server on a VPS: Java, RAM, ports and a systemd service

Run a Minecraft Java server on a Linux VPS: the right Java version, enough RAM, port 25565, a systemd service and backups — and why per-core speed matters.

Published ~11 min read

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 -Xmx must 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.

Ubuntu 24.04 · Debian 13 — Java 25 is packaged
sudo apt update
sudo apt install -y openjdk-25-jre-headless      # for 1.21.x, use openjdk-21-jre-headless
java -version

Debian 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:

Debian 12 — Temurin 25 from Adoptium
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
Rocky · Alma 9
# 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 -version

If 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?

  1. 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
  2. 2Download the server jar

    Take the server.jar URL 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
  3. 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:

server.properties (excerpt)
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=true

How 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.

install an RCON client for the stop command
# 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/rconclt
/etc/minecraft/rcon.conf — readable only by the service user
sudo 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
/etc/systemd/system/minecraft.service
[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.target
start and verify the clean stop
sudo 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 exits

Which port does a Minecraft server need?

Java Edition listens on TCP 25565. Open exactly that, and no more:

firewall
# ufw (Debian, Ubuntu)
sudo ufw allow 25565/tcp comment 'Minecraft'

# firewalld (Rocky, Alma)
sudo firewall-cmd --permanent --add-port=25565/tcp && sudo firewall-cmd --reload

Leave 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:

/opt/minecraft/backup.sh
#!/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 --
run it nightly from cron
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.

Related articles

All guides