Setting up your own Minecraft server takes 20-60 minutes and costs $5-60 monthly, depending on your player count. You get complete control over your gaming experience, choose your own mods, and create the exact world you want.
This guide covers self-hosting on a VPS or cloud server with optimized performance and proper security. We’ll show you production-ready configurations used by professional server hosts, with step-by-step instructions for security hardening, performance tuning, and automated maintenance.
Hosting Options Explained
Self-Hosting on Your PC
Running the server on your computer gives you immediate access without monthly fees. Your PC must remain running at all times, which can lead to higher electricity costs and performance issues when multitasking. Security becomes your responsibility entirely.
Self-Hosting on a VPS or Cloud Server
A VPS is a remote computer you rent that runs independently from your home setup. Unlike shared hosting, you get dedicated resources and full control over the server software.
VPS plans suitable for Minecraft start at $5-8/month for 1-10 players. Key features to look for:
- Dedicated CPU cores (not shared vCPU)
- NVMe SSD storage (3-5x faster than SATA)
- Unmetered bandwidth (2-3 Mbps per player minimum)
- Full root access (required for this guide)
- Snapshots/backups (critical for world protection)
Your server stays online continuously without relying on your personal computer. Players can connect anytime, and your home internet doesn’t affect server performance. You can scale resources up or down based on player count without buying new hardware.
Renting a Managed Server
Managed hosting providers offer one-click setups but cost $15-60+/month with less customization.
Hosting Cost Comparison
| Hosting Type | Monthly Cost | Best For | Setup Time | Key Limitation |
|---|---|---|---|---|
| Home PC | $5-15 electricity | 2-5 close friends | 30 mins | Unreliable uptime |
| VPS | $4-15 | 5-20 players | 45 mins | Requires Linux knowledge |
| Managed | $15-60+ | 10-50+ players | 15 mins | Limited customization |
| Dedicated | $50-200+ | Large communities | 60+ mins | Overkill for <100 players |
Pro Tip: Start with our mid-tier VPS even for small servers. The overhead gives you room to test plugins, create backups, and handle traffic spikes without upgrading immediately.
Minimum Requirements for Self-Hosting
CPU: Modern quad-core (Intel i3-13100 or AMD Ryzen 5 7600). Single-core speed matters most for Minecraft’s single-threaded world simulation. ARM-based cloud instances (AWS Graviton, Oracle Ampere) provide excellent price-to-performance but may have compatibility issues with some plugins.
RAM: Allocate based on your server type:
- 4GB: Vanilla (1-10 players)
- 6-8GB: Light mods/plugins (10-20 players)
- 12GB+: Heavy modpacks (20+ players)
- Always reserve 2GB for OS overhead
Storage: NVMe SSD strongly recommended for 20+ players or worlds >5GB. SATA SSD minimum. Never use HDD – world loading will create unacceptable lag. Budget 10-20GB for the server, plus 5-10GB per 1000 chunks of world generation.
Network: 2-3 Mbps upload per player minimum for Minecraft 1.20 and above. For 10 concurrent players, expect 20-30 Mbps sustained usage. Under 50ms latency is ideal – test your connection to the datacenter before committing to a provider.
OS: Ubuntu Server 24.04 LTS or Debian 12 recommended (lower resource usage than Windows Server, free, and better documented for Minecraft).
Preparing Your Environment
Secure Your Server
Connect to your VPS using SSH:
ssh root@your_server_ip
Create a non-root user:
adduser minecraft
usermod -aG sudo minecraft
Set up SSH keys (more secure than passwords):
ssh-keygen -t ed25519 -C "minecraft-server"
ssh-copy-id minecraft@your_server_ip
Test the new account in a second terminal:
ssh minecraft@your_server_ip
Disable root login:
sudo nano /etc/ssh/sshd_config
Change these lines:
PermitRootLogin no
PasswordAuthentication no
Restart SSH:
sudo systemctl restart sshd
Test your sudo user login in a second terminal before logging out of root.
System Updates and Essential Packages
Update all packages:
sudo apt update
sudo apt upgrade -y
sudo reboot
Wait two minutes, then reconnect. Set timezone for consistent logs:
sudo timedatectl set-timezone UTC
Install required packages:
sudo apt install screen wget curl jq ufw fail2ban unattended-upgrades pigz -y
Firewall Configuration
Configure UFW:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw limit 25565/tcp comment 'Minecraft'
sudo ufw enable
The limit rule provides rate-limiting protection against connection floods and automatically applies to both IPv4 and IPv6.
Note: If adding other services later (web panel, voice chat), you’ll need to allow their ports.
Verify status:
sudo ufw status verbose
Automated Security
Enable automatic security updates:
sudo dpkg-reconfigure -plow unattended-upgrades
Select “Yes” when prompted.
Enable fail2ban:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Installing Java
Minecraft requires Java to run. Different versions need specific Java versions.
| Minecraft Version | Required Java |
|---|---|
| 1.21.x | Java 21 LTS or Java 23+ |
| 1.20.5-1.20.6 | Java 21 LTS |
| 1.20.1-1.20.4 | Java 17 LTS |
| 1.18-1.19.x | Java 17 LTS |
| 1.17.x | Java 16 |
| 1.12-1.16.5 | Java 8 |
Install Java 21:
sudo apt install openjdk-21-jre-headless -y
Verify installation:
java -version
For older Minecraft versions, install openjdk-17-jre-headless or openjdk-8-jre-headless instead.
Note: Java 21 LTS is the current standard for Minecraft 1.21.x servers. Java 23 is also supported and stable, but Java 21 is recommended for long-term stability. Never use Java 22 as it is a non-LTS release.
Downloading Server Software
Different server software offers different features and performance.
Server Software Options
- Vanilla: Official Mojang server software. Pure vanilla experience, baseline performance.
- Paper (Recommended): 40-80% better performance than vanilla plus plugin support. Most public servers use Paper.
- Folia: Paper’s multi-threaded fork. Best for 100+ player servers with compatible plugins.
- Purpur: Popular Paper fork with extra gameplay features and configuration options.
- Fabric: Mod support with performance similar to vanilla.
- Forge: Large mod ecosystem but heavier than Fabric; both support modern versions.
- Geyser/Floodgate: Allows Bedrock Edition players (mobile/console) to join Java servers. Download separately from geysermc.org and install in the plugins folder.
Creating Server Directory
mkdir -p ~/minecraft_server
cd ~/minecraft_server
Downloading Server Files
For Paper (recommended):
VERSION="1.21.10"
BUILD=$(curl -s "https://api.papermc.io/v2/projects/paper/versions/${VERSION}" | jq -r '.builds[-1]')
wget "https://api.papermc.io/v2/projects/paper/versions/${VERSION}/builds/${BUILD}/downloads/paper-${VERSION}-${BUILD}.jar" -O server.jar
Verify download:
ls -lh server.jar
You should see a file around 40-50MB.
Creating an Optimized Start Script
Create your start script:
nano start.sh
For servers with 4-6GB RAM (G1GC):
These flags are optimized for Java 21. If using different Java versions, consult the current JVM documentation.
#!/bin/bash
java -Xms4G -Xmx4G \
-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 \
-jar server.jar nogui
For servers with 8GB+ RAM (ZGC – Recommended for Java 21+):
ZGC requires Java 17 or higher. Java 21 or newer is recommended for best performance.
#!/bin/bash
java -Xms8G -Xmx8G \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+DisableExplicitGC \
-XX:+AlwaysPreTouch \
-XX:+ParallelRefProcEnabled \
-jar server.jar nogui
ZGC reduces lag spikes from 100+ milliseconds to under 1 millisecond on servers with 8GB+ RAM. ZGC uses 10-15% more RAM than G1GC but provides much smoother performance. Keep this memory overhead in mind when allocating RAM.
Note: ZGC is recommended for servers with consistent high player counts (15+ concurrent players). For smaller servers (1-10 players), G1GC with the above flags will provide excellent performance with lower memory overhead.
Note: Java 23 and newer enable ZGenerational by default, so the flag is optional for Java 23+. For Java 21 and 22, always include the ZGenerational flag for optimal performance.
For ZGC, keep Xms equal to Xmx because ZGC handles memory allocation differently and performs best with equal values. For G1GC on Java 21+, set Xms to 50-75% of Xmx. For Java 17 and below, set Xms equal to Xmx.
Never allocate more than 80% of your total system RAM.
Make the script executable:
chmod +x start.sh
Accepting the EULA
Run your start script once:
./start.sh
The server creates files, then stops. Edit eula.txt:
nano eula.txt
Change eula=false to eula=true then save.
Setting Up as a System Service
Create a service file:
sudo nano /etc/systemd/system/minecraft.service
Add this configuration:
[Unit]
Description=Minecraft Server
After=network.target
[Service]
Type=simple
User=minecraft
WorkingDirectory=/home/minecraft/minecraft_server
ExecStart=/home/minecraft/minecraft_server/start.sh
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Reload systemd and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable minecraft
sudo systemctl start minecraft
sudo systemctl status minecraft
You should see “active (running)” in green.
Managing the Service
View live logs:
sudo journalctl -u minecraft -f
Restart the server:
sudo systemctl restart minecraft
Stop the server:
sudo systemctl stop minecraft
Configuration
Stop the server first:
sudo systemctl stop minecraft
Edit server.properties:
nano server.properties
Key settings:
# Network
server-port=25565
max-players=20
# Gameplay
difficulty=normal
gamemode=survival
pvp=true
hardcore=false
enforce-secure-profile=true # Requires valid Mojang/Microsoft accounts
# Performance
view-distance=12
simulation-distance=8
network-compression-threshold=512
# Security
enable-command-block=false
white-list=false
Save changes and restart:
sudo systemctl start minecraft
Paper Configuration
Paper 1.20+ uses config/paper-global.yml and config/paper-world-defaults.yml. Default settings are highly optimized. For advanced tuning, see docs.papermc.io/paper/reference/configuration.
Edit spigot.yml to reduce entity processing range:
nano spigot.yml
Set entity-activation-range animals/monsters to 48, mob-spawn-range to 6.
Player Management
Make operators in console:
op PlayerName
Enable whitelist:
whitelist on
whitelist add PlayerName
Network Configuration
Port Forwarding (Home Hosting Only)
Access your router’s admin panel at one of these common IPs: 192.168.1.1, 192.168.0.1, 10.0.0.1, or 192.168.2.1.
Create a port forwarding rule:
- Service Name: Minecraft
- External Port: 25565
- Internal Port: 25565
- Internal IP: Your server’s local IP (find with ip addr)
- Protocol: TCP and UDP
For home hosting: Consider Dynamic DNS (DuckDNS, No-IP) if your ISP changes your IP regularly.
Testing Your Connection
Find your public IP:
curl ifconfig.me
Check port at mctoolbox.com/port-checker
IPv6 Configuration
Leave server-ip= blank in server.properties to auto-enable IPv4 and IPv6.
Verify IPv6 is listening:
sudo ss -tlnp | grep 25565
You should see entries showing both 0.0.0.0:25565 (IPv4) and :::25565 (IPv6).
Share your public IP with players to connect.
Connecting to Your Server
Launch Minecraft Java Edition. Ensure you’re using the same version your server runs.
Click “Multiplayer” then “Add Server.”
Enter:
- Server Name: Any name you choose
- Server Address: Your server’s IP
Click “Done” to save. Green connection bars indicate success. Click the server to connect.
Troubleshooting
Connection timed out:
Verify your firewall settings with the command sudo ufw status. Check if the server is running with the command sudo systemctl status minecraft. Test port accessibility at mctoolbox.com/port-checker.
Wrong Java version:
Error: Unsupported class file major version 65
Install Java 21:
sudo apt install openjdk-21-jre-headless -y
Out of memory:
java.lang.OutOfMemoryError: Java heap space
Increase Xmx in start.sh or reduce player count.
Performance Issues:
Check TPS in console: /tps (20 = perfect, below 15 = lag)
Install Spark profiler for detailed analysis:
mkdir -p ~/minecraft_server/plugins
cd ~/minecraft_server/plugins
wget https://ci.lucko.me/job/spark/lastSuccessfulBuild/artifact/spark-bukkit/build/libs/spark-bukkit.jar
Restart server, then use /spark profiler in-game.
For advanced ZGC performance monitoring, add this to your start script:
-Xlog:gc*:file=gc.log:time,uptime:filecount=5,filesize=10M
Maintenance
Automated Backup System
Create a backup script:
nano ~/backup-minecraft.sh
Add:
#!/bin/bash
SERVER_DIR="/home/minecraft/minecraft_server"
BACKUP_DIR="/home/minecraft/backups"
MAX_BACKUPS=7
mkdir -p "$BACKUP_DIR"
if systemctl is-active --quiet minecraft; then
sudo systemctl stop minecraft
sleep 5
fi
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.tar.gz"
if command -v pigz &> /dev/null; then
tar -cf - -C "$SERVER_DIR" world world_nether world_the_end server.properties ops.json whitelist.json | pigz > "$BACKUP_FILE"
else
tar -czf "$BACKUP_FILE" -C "$SERVER_DIR" world world_nether world_the_end server.properties ops.json whitelist.json
fi
sudo systemctl start minecraft
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$MAX_BACKUPS -delete
echo "$DATE - Backup created: $BACKUP_FILE ($(du -h "$BACKUP_FILE" | cut -f1))" >> "$BACKUP_DIR/backup.log"
Make executable:
chmod +x ~/backup-minecraft.sh
Schedule daily backups:
crontab -e
Add:
0 4 * * * /home/minecraft/backup-minecraft.sh
Adjust MAX_BACKUPS based on backup frequency (7 for daily, 4 for weekly).
Restoring from Backup
Stop server:
sudo systemctl stop minecraft
Extract backup:
cd ~/minecraft_server
tar -xzf ~/backups/backup_YYYY-MM-DD_HH-MM-SS.tar.gz
Start server:
sudo systemctl start minecraft
Server Updates
Stop the server:
sudo systemctl stop minecraft
Backup current version:
cp ~/minecraft_server/server.jar ~/minecraft_server/server.jar.backup
Check plugin compatibility at papermc.io/downloads before major version updates.
Download new version:
cd ~/minecraft_server
VERSION="1.21.10"
BUILD=$(curl -s "https://api.papermc.io/v2/projects/paper/versions/${VERSION}" | jq -r '.builds[-1]')
wget "https://api.papermc.io/v2/projects/paper/versions/${VERSION}/builds/${BUILD}/downloads/paper-${VERSION}-${BUILD}.jar" -O server.jar
Start the server:
sudo systemctl start minecraft
Monitor for errors:
sudo journalctl -u minecraft -f
If problems occur, restore the backup:
cp ~/minecraft_server/server.jar.backup ~/minecraft_server/server.jar
sudo systemctl restart minecraft
Regular Maintenance
Run weekly:
sudo apt update && sudo apt upgrade # System updates
df -h # Check disk space
sudo journalctl -u minecraft --since "7 days ago" | grep ERROR # Check errors
Verify automatic updates are working:
sudo systemctl status unattended-upgrades
Conclusion
You now have a production-ready Minecraft server with optimized JVM settings, automated backups, and proper security. Keep your server updated for security and performance. Monitor resource usage through logs and address performance issues before they affect players.
Install plugins from hangar.papermc.io or modrinth.com to extend functionality. Start with friends, learn the systems, then expand as you gain experience.
