Minecraft Server Setup on a VDS: Paper, systemd, DDoS Defense
A Minecraft server on a VDS works best when you run Paper under a dedicated systemd service, give the JVM a fixed heap, and put the public IP behind DDoS filtering. This guide walks through all of it on Ubuntu 24.04, from choosing resources to locking down the firewall.
Game servers are a common DDoS target. Rivalries, griefing disputes, and extortion attempts all show up in the logs sooner or later. Hardening the machine alone won't stop a flood. Most of the work happens upstream of your VDS.
Choosing a VDS for Minecraft Java
Minecraft's main game loop is largely single-threaded. One tick has a 50 ms budget (20 TPS), and a slow core means lag no matter how many cores you have. Prioritize in this order:
- Single-thread CPU speed. Prefer a plan with dedicated or well-isolated vCPUs over a heavily oversold one.
- RAM. Enough for the heap plus the OS and JVM overhead (see below).
- NVMe or fast SSD storage. World saving and chunk loading are I/O-sensitive.
- Location. Pick the region closest to most of your players. Fremont, California suits US West, Frankfurt suits Europe, and İzmir suits players in Turkey and nearby regions.
- DDoS protection on the IP you publish. More on this below.
As a rough starting point, a small friends-and-community server runs on 2 vCPUs and 4 GB RAM. A public survival server with plugins and 50+ concurrent players usually needs 8 GB or more and a fast core. Measure with real players before upgrading. Nixcon's VDS plans run on VMware vSphere, so resources can be resized as your player count grows.
Prepare the server
Log in, update, and create a dedicated unprivileged user. Never run a game server as root.
sudo apt update && sudo apt -y upgrade
sudo apt -y install openjdk-21-jre-headless curl jq ufw
sudo adduser --system --group --home /opt/minecraft minecraft
java -version
Current Minecraft releases (1.20.5 and later) require Java 21. Check the Paper documentation if you run an older version.
Install Paper
Paper is a high-performance fork of Spigot with better tick performance and many fixes. Download the latest build from the official PaperMC downloads page (papermc.io/downloads) or its API, then place it in the server directory:
sudo -u minecraft mkdir -p /opt/minecraft/server
cd /opt/minecraft/server
# Replace the URL with the build link from papermc.io/downloads
sudo -u minecraft curl -fLo paper.jar "<PAPER_DOWNLOAD_URL>"
echo "eula=true" | sudo -u minecraft tee eula.txt
By setting eula=true you accept the Minecraft EULA, so read it first. Don't hardcode a version you copied from a random tutorial. Pick the current build.
Tune RAM and JVM flags
Set the minimum and maximum heap to the same value. This avoids resize pauses. Never give the JVM all the RAM on the machine. The OS, page cache, and JVM native memory (metaspace, threads, buffers) need room.
| VDS RAM | Suggested heap (-Xms/-Xmx) |
|---|---|
| 4 GB | 3G |
| 8 GB | 6G |
| 16 GB | 12G |
A larger heap isn't always faster. Oversized heaps can increase garbage-collection work. Start conservatively and watch actual usage.
The widely used "Aikar flags" tune the G1 garbage collector for Minecraft. Save them in a start script:
sudo -u minecraft tee /opt/minecraft/server/start.sh >/dev/null <<'EOF'
#!/bin/sh
exec java -Xms6G -Xmx6G \
-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 \
-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch \
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M \
-XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 \
-XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 \
-XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 \
-XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 \
-Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true \
-jar paper.jar --nogui
EOF
sudo chmod +x /opt/minecraft/server/start.sh
Edit -Xms/-Xmx to match your plan. Two quick wins in server.properties: lower view-distance (for example 8 to 10) and set simulation-distance to 6 or 8. These cut CPU and bandwidth more than any flag.
Run it as a systemd service
Running inside screen works until the machine reboots. A systemd unit starts the server at boot, restarts it on a crash, and logs to the journal. To keep console access, pair the service with a socket so you can send commands:
# /etc/systemd/system/minecraft.socket
[Unit]
Description=Minecraft console socket
[Socket]
ListenFIFO=%t/minecraft.stdin
SocketUser=minecraft
SocketGroup=minecraft
SocketMode=0660
RemoveOnStop=true
# /etc/systemd/system/minecraft.service
[Unit]
Description=Paper Minecraft Server
After=network-online.target
Wants=network-online.target
Requires=minecraft.socket
[Service]
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft/server
ExecStart=/opt/minecraft/server/start.sh
ExecStop=/bin/sh -c 'echo stop > /run/minecraft.stdin'
Sockets=minecraft.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=10
TimeoutStopSec=120
KillMode=mixed
NoNewPrivileges=true
ProtectSystem=full
ReadWritePaths=/opt/minecraft
[Install]
WantedBy=multi-user.target
Enable and use it:
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft.socket minecraft.service
journalctl -u minecraft -f
echo "say Hello from systemd" | sudo tee /run/minecraft.stdin
A clean systemctl stop minecraft sends stop so the world saves before the process exits. The long TimeoutStopSec gives large worlds time to flush.
Lock down the firewall
Open only what players need. Restrict SSH to your own address if you have a static one.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw allow 25565/tcp
sudo ufw enable
If you add Bedrock cross-play through Geyser, also open UDP 19132. Keep RCON (25575) and the query port closed to the internet. If you need RCON, bind it to localhost and set a strong password. Keep online-mode=true unless the server sits behind a proxy such as Velocity that handles authentication. In that case, firewall the backend so only the proxy can reach it.
What a DDoS looks like against Minecraft
| Attack type | What it does | Where it's stopped |
|---|---|---|
| Volumetric (UDP/ICMP floods) | Saturates the link | Upstream network only |
| TCP SYN/ACK floods | Exhausts connection state | Upstream filtering |
| Handshake or login floods | Many fake joins burn CPU | Upstream plus proxy/plugin limits |
| Bot joins | Real protocol logins, many accounts | Application-level rate limits |
The key point is that a volumetric flood fills the pipe before your VDS sees it. No iptables rule or plugin on the server can fix that. Filtering has to happen on the network in front of the server. For a deeper breakdown, see our guide on DDoS attack types and symptoms.
Use a DDoS-protected IP
Host the server on an IP address that is filtered at the network edge. Nixcon operates its own network (AS40368) with locations in İzmir, Frankfurt, and Fremont, and offers DDoS protection and firewall services so attack traffic is scrubbed before it reaches your VDS. Ask your provider how Minecraft traffic is handled, whether you can adjust filter rules for TCP 25565, and whether the filter allows legitimate connection bursts, such as after a restart or an event.
Operators with their own ASN and IP block can use a different approach: GRE-tunneled BGP, which delivers clean traffic to their own prefixes.
Application-level hardening
Edge filtering and server settings complement each other:
- Keep
connection-throttleinbukkit.ymlat its default or higher, so rapid reconnects from one address are rejected. - Use a proxy (Velocity) and expose only the proxy. The backend Paper server should accept connections only from the proxy's address.
- Use an anti-bot plugin that verifies new joins. Choose maintained ones and test them on a staging server first.
- Never publish your origin IP. Don't leave old A records, a leaky Dynmap hostname, or a forum post pointing at the real address.
- Whitelist during incidents (
whitelist on) to buy time while you investigate.
Common mistakes and fixes
- Server runs out of memory and the OOM killer ends it. The heap is too close to total RAM. Lower
-Xmxby 1 to 2 GB and checkdmesg | grep -i oom. - TPS drops with few players. Check
/spark profiler(Spark plugin) for the cause. Common culprits are entity farms, large redstone clocks, and a highview-distance. - Service restarts in a loop. Run
journalctl -u minecraft -n 100. Usually it's the wrong Java version or an unaccepted EULA. - Can't connect from outside. Confirm
ss -tlnp | grep 25565, then the UFW rule, then any provider-side firewall. - Attack continues after you change the IP. The origin was leaked through DNS history or a plugin. Rotate and keep it private.
Monitor and prepare
Watch TPS, memory, and traffic patterns so you notice trouble early. Flow-based monitoring such as NixMon is more useful for operators running multiple servers or their own network. You can also check how your provider's network reaches players using the public looking glass for ping, traceroute, and BGP route queries from İzmir, Frankfurt, and the US.
Back up the world directories on a schedule, and test a restore. DDoS protection won't help you if a plugin corrupts your data.
Frequently asked questions
How much RAM does a Paper Minecraft server need?
A small private server runs well on a 3 GB heap (4 GB VDS). Public servers with plugins and dozens of players often need 6 to 12 GB of heap. Set -Xms equal to -Xmx and leave 1 to 2 GB for the OS and JVM overhead.
Can I stop a Minecraft DDoS attack with iptables or a plugin?
Only small application-level abuse such as bot joins. Volumetric and state-exhaustion floods saturate the link or the network stack before your rules help, so you need filtering upstream of the VDS.
Why use systemd instead of screen for a Minecraft server?
systemd starts the server on boot, restarts it after crashes, logs to the journal, and stops it cleanly so the world saves. A socket unit still lets you send console commands.
Which Java version does Paper need?
Recent Minecraft versions (1.20.5 and later) need Java 21. Check the PaperMC documentation for the version you plan to run, since older releases use older Java versions.