Minecraft Hosting: Architecture, Optimization, Load Management, Security, and Scalability
Minecraft server hosting presents unique challenges due to Java's memory management, single-threaded tick processing, and real-time player interactions. Running production-grade Minecraft servers requires understanding Java Virtual Machine (JVM) tuning, server software optimization, network architecture, and scaling strategies.
This guide provides a comprehensive technical analysis of Minecraft server infrastructure, from JVM garbage collection tuning to multi-proxy network architectures, with practical configuration examples for high-performance Minecraft hosting.
Java Load Characteristics and TPS (Ticks Per Second)
Understanding Minecraft Server Performance
Minecraft servers operate on a tick-based system where game logic executes 20 times per second (20 TPS). Each tick processes:
- Entity movement and AI
- Block updates and redstone circuits
- Chunk loading and generation
- Player actions and inventory
- Plugin/server logic
Performance Bottlenecks:
-
Main Thread Blocking: Single-threaded game loop blocks on:
- Chunk I/O operations
- Plugin synchronous operations
- Complex redstone circuits
- Entity pathfinding
-
Memory Pressure: Java heap allocation patterns:
- Chunk data: ~1-2 MB per loaded chunk
- Entity data: ~1-5 KB per entity
- Player data: ~10-50 KB per player
- Plugin overhead: Variable (10-100 MB per plugin)
-
I/O Operations: Disk access for:
- World saves (synchronous, blocks main thread)
- Log files
- Plugin data files
TPS Measurement and Monitoring
TPS Calculation:
// Bukkit/Spigot TPS calculation
long[] tickTimes = server.getTickTimes();
double averageTickTime = Arrays.stream(tickTimes).average().orElse(0.0);
double tps = 1000.0 / (averageTickTime / 1000000.0);
Target Performance Metrics:
| Metric | Target | Warning | Critical |
|---|---|---|---|
| TPS | 20.0 | 19.5 | < 19.0 |
| Average Tick Time | < 50ms | 50-100ms | > 100ms |
| Memory Usage | < 80% | 80-90% | > 90% |
| Chunk Loading Time | < 100ms | 100-500ms | > 500ms |
| Entity Count | < 500 | 500-1000 | > 1000 |
Monitoring Script:
#!/bin/bash
# minecraft-monitor.sh
SERVER_LOG="/opt/minecraft/server/logs/latest.log"
# Extract TPS from server log (if using Paper/Spigot)
tps=$(grep "TPS" "$SERVER_LOG" | tail -1 | grep -oP '\d+\.\d+' | head -1)
# Check if server is responsive
if timeout 1 bash -c "echo > /dev/tcp/localhost/25565" 2>/dev/null; then
echo "Server: ONLINE"
else
echo "Server: OFFLINE"
fi
# Check memory usage
memory=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
echo "Memory Usage: ${memory}%"
# Check CPU usage
cpu=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
echo "CPU Usage: ${cpu}%"
# Player count (if server is online)
players=$(timeout 1 nc localhost 25565 < /dev/null 2>/dev/null | grep -oP 'players online: \K\d+' || echo "N/A")
echo "Players Online: ${players}"
Server Software: Paper, Spigot, and Purpur
Paper: Recommended for Production
Paper is a high-performance fork of Spigot that includes optimizations for:
- Async chunk loading
- Improved entity collision detection
- Optimized redstone circuits
- Better plugin API
Paper Installation:
#!/bin/bash
# install-paper.sh
MC_VERSION="1.20.1"
PAPER_BUILD="latest"
# Download Paper
curl -o paper.jar "https://api.papermc.io/v2/projects/paper/versions/${MC_VERSION}/builds/${PAPER_BUILD}/downloads/paper-${MC_VERSION}-${PAPER_BUILD}.jar"
# Create server directory
mkdir -p /opt/minecraft/server
cd /opt/minecraft/server
# Move JAR
mv paper.jar server.jar
# Accept EULA
echo "eula=true" > eula.txt
# Create startup script
cat > start.sh <<'EOF'
#!/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 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui
EOF
chmod +x start.sh
Spigot: Legacy Performance Fork
Spigot was the original performance fork of CraftBukkit. While Paper is generally superior, Spigot is still used for compatibility reasons.
Spigot Build Tools:
# Build Spigot from source
git clone https://hub.spigotmc.org/stash/scm/spigot/buildtools.git
cd buildtools
java -jar BuildTools.jar --rev 1.20.1
Purpur: Maximum Performance
Purpur is a fork of Paper with additional optimizations and features:
- Advanced performance settings
- Customizable entity limits
- Better chunk loading
- More configuration options
Purpur Configuration Highlights:
# purpur.yml
settings:
tick-when-empty: false
entities-target-with-skull: 0
chunks:
entity-per-chunk:
save:
zombie: 32
skeleton: 32
creeper: 16
world-settings:
default:
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
water: 8
villagers: 16
flying-monsters: 48
Server Software Comparison
| Feature | Vanilla | Spigot | Paper | Purpur |
|---|---|---|---|---|
| Performance | Baseline | +30% | +50-80% | +80-100% |
| Plugin Support | No | Yes | Yes | Yes |
| Async Operations | No | Limited | Yes | Yes |
| Configurability | Low | Medium | High | Very High |
| Update Frequency | Regular | Slow | Fast | Fast |
| Memory Efficiency | Poor | Good | Excellent | Excellent |
Optimizing Paper/Spigot/Purpur Servers
JVM Arguments for Optimal Performance
Aikar's Flags (Recommended):
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 \
-Dusing.aikars.flags=https://mcflags.emc.gs \
-Daikars.new.flags=true \
-jar server.jar nogui
Explanation of Key Flags:
-Xms4G -Xmx4G: Allocate 4GB heap (set equal to prevent resizing)-XX:+UseG1GC: Use G1 garbage collector (optimal for Minecraft)-XX:MaxGCPauseMillis=200: Target 200ms max GC pause-XX:G1NewSizePercent=30: Allocate 30% of heap for new objects-XX:+AlwaysPreTouch: Pre-allocate memory to reduce latency-XX:MaxTenuringThreshold=1: Move objects to old generation quickly
Paper Configuration Optimization
paper-global.yml:
# paper-global.yml
chunk-loading:
enable-frustum-priority: true
global-max-chunk-load-rate: -1
max-concurrent-sends: 2
min-load-radius: 2
player-max-chunk-load-rate: 100.0
target-player-chunk-send-rate: 100.0
misc:
compression-level: -1 # -1 to 9, -1 = default (6)
log-player-ip-addresses: false
max-joins-per-tick: 5
player-auto-save-interval: -1
save-player-data: true
use-alternative-luck-formula: true
timings:
enabled: true
hidden-config-entries: []
history-interval: 300
server-name: "Minecraft Server"
server-ip: ""
verbose: true
paper-world-defaults.yml:
# paper-world-defaults.yml
chunk-loading:
autoconfig-send-distance: true
enable-frustum-priority: true
max-concurrent-sends: 2
min-load-radius: 2
player-max-chunk-load-rate: 100.0
target-player-chunk-send-rate: 100.0
entity-per-chunk:
max-entities-per-chunk:
area-effect-cloud: 8
arrow: 16
dragon-fireball: 3
egg: 8
ender-pearl: 8
experience-orb: 16
fireball: 8
firework: 8
llama-spit: 3
shulker-bullet: 8
small-fireball: 8
snowball: 8
spectral-arrow: 16
trident: 16
wither-skull: 4
entities:
entities:
arrow:
despawn-rate: -1
ender-pearl:
despawn-rate: -1
experience-orb:
despawn-rate: -1
item:
despawn-rate: -1
ignore-items:
- DIAMOND
- NETHERITE_INGOT
Server.properties Optimization
# server.properties
max-players=100
view-distance=10 # Reduce from 32 to 10 for performance
simulation-distance=8 # Reduce from 32 to 8
entity-broadcast-range-percentage=100
max-world-size=29999984
network-compression-threshold=256
online-mode=true
prevent-proxy-connections=false
server-ip=
server-port=25565
use-native-transport=true
enable-jmx-monitoring=false
enable-status=true
broadcast-rcon-to-ops=true
broadcast-console-to-ops=true
enable-command-block=false
enable-query=false
enable-rcon=false
sync-chunk-writes=true
enable-whitelist=false
enforce-whitelist=false
white-list=false
spawn-npcs=true
spawn-animals=true
spawn-monsters=true
spawn-protection=16
max-tick-time=60000
use-native-transport=true
max-chained-neighbor-updates=1000000
rate-limit=0
Deploying Minecraft Servers on VPS/VDS
Server Requirements by Player Count
| Players | RAM | CPU Cores | Storage | Bandwidth |
|---|---|---|---|---|
| 1-10 | 2GB | 2 | 10GB | 10 Mbps |
| 10-25 | 4GB | 2-4 | 25GB | 25 Mbps |
| 25-50 | 6-8GB | 4 | 50GB | 50 Mbps |
| 50-100 | 8-12GB | 4-6 | 100GB | 100 Mbps |
| 100-200 | 12-16GB | 6-8 | 200GB | 150+ Mbps |
| 200+ | 16GB+ | 8+ | 500GB+ | 200+ Mbps |
Installation Script for VPS
#!/bin/bash
# minecraft-server-setup.sh
set -e
MC_VERSION="1.20.1"
SERVER_DIR="/opt/minecraft/server"
RAM_ALLOCATION="4G"
# Update system
apt update && apt upgrade -y
# Install Java 17 (required for Minecraft 1.17+)
apt install -y openjdk-17-jdk openjdk-17-jre
# Create minecraft user
useradd -r -s /bin/false -d "$SERVER_DIR" minecraft
mkdir -p "$SERVER_DIR"
chown minecraft:minecraft "$SERVER_DIR"
# Download Paper
cd "$SERVER_DIR"
wget -O server.jar "https://api.papermc.io/v2/projects/paper/versions/${MC_VERSION}/builds/latest/downloads/paper-${MC_VERSION}-latest.jar"
# Accept EULA
echo "eula=true" > eula.txt
# Create startup script
cat > start.sh <<EOF
#!/bin/bash
cd "$SERVER_DIR"
java -Xms${RAM_ALLOCATION} -Xmx${RAM_ALLOCATION} -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 server.jar nogui
EOF
chmod +x start.sh
chown -R minecraft:minecraft "$SERVER_DIR"
# Create systemd service
cat > /etc/systemd/system/minecraft.service <<EOF
[Unit]
Description=Minecraft Server
After=network.target
[Service]
Type=simple
User=minecraft
WorkingDirectory=$SERVER_DIR
ExecStart=/bin/bash $SERVER_DIR/start.sh
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable minecraft
systemctl start minecraft
echo "Minecraft server installed and started!"
echo "Check status: systemctl status minecraft"
echo "View logs: journalctl -u minecraft -f"
Firewall Configuration
# Allow Minecraft port
ufw allow 25565/tcp comment 'Minecraft Server'
# Allow RCON if enabled (optional)
ufw allow 25575/tcp comment 'Minecraft RCON'
# Allow query port (optional)
ufw allow 25565/udp comment 'Minecraft Query'
Backup Script
#!/bin/bash
# minecraft-backup.sh
SERVER_DIR="/opt/minecraft/server"
BACKUP_DIR="/opt/minecraft/backups"
RETENTION_DAYS=7
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Create timestamped backup
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/world_${TIMESTAMP}.tar.gz"
# Send save-all command to server
screen -S minecraft -X stuff "save-all$(printf \\r)"
# Wait for save to complete
sleep 5
# Create compressed backup
tar -czf "$BACKUP_FILE" -C "$SERVER_DIR" world world_nether world_the_end
# Remove old backups
find "$BACKUP_DIR" -name "world_*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup created: $BACKUP_FILE"
Automated Backups (Cron):
# Add to crontab (crontab -e)
0 */6 * * * /opt/minecraft/scripts/backup.sh # Every 6 hours
0 0 * * * /opt/minecraft/scripts/backup.sh # Daily at midnight
Scaling: BungeeCord and Velocity
BungeeCord: Traditional Proxy
BungeeCord is a proxy server that connects multiple Minecraft servers together, allowing players to switch between servers without disconnecting.
Architecture:
Internet
↓
BungeeCord
(Port 25565)
↓
┌──────────────┼──────────────┐
↓ ↓ ↓
Lobby Server Game Server Survival Server
(Port 25566) (Port 25567) (Port 25568)
BungeeCord Configuration:
# config.yml
listeners:
- query_port: 25577
motd: '&1My Minecraft Network'
tab_list: GLOBAL_PING
query_enabled: false
proxy_protocol: false
forced_hosts:
pvp.md-5.net: pvp
ping_passthrough: false
priorities:
- lobby
bind_local_address: true
host: 0.0.0.0:25565
max_players: 100
tab_size: 60
force_default_server: false
servers:
lobby:
address: localhost:25566
restricted: false
motd: '&1Just Another Lobby - Use /server to join a game!'
game:
address: localhost:25567
restricted: false
motd: '&1Minigames Server'
survival:
address: localhost:25568
restricted: false
motd: '&1Survival Server'
ip_forward: true
online_mode: true
BungeeCord Installation:
#!/bin/bash
# install-bungeecord.sh
BUNGEE_VERSION="latest"
BUNGEE_DIR="/opt/minecraft/bungeecord"
mkdir -p "$BUNGEE_DIR"
cd "$BUNGEE_DIR"
# Download BungeeCord
wget -O bungeecord.jar "https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar"
# Create startup script
cat > start.sh <<EOF
#!/bin/bash
java -Xms512M -Xmx512M -jar bungeecord.jar
EOF
chmod +x start.sh
Velocity: Modern High-Performance Proxy
Velocity is a modern proxy designed for performance, replacing BungeeCord in many production environments.
Velocity Advantages:
- Performance: 2-3x faster than BungeeCord
- Modern API: Built for Paper/Spigot 1.13+
- Better plugin ecosystem: Modern plugin development
- Reduced memory usage: More efficient resource utilization
Velocity Configuration:
# velocity.toml
config-version = "2.6"
[servers]
lobby = "127.0.0.1:25566"
game = "127.0.0.1:25567"
survival = "127.0.0.1:25568"
[forced-hosts]
"lobby.example.com" = ["lobby"]
"game.example.com" = ["game"]
try = ["lobby"]
[advanced]
compression-threshold = 256
compression-level = -1
login-ratelimit = 3000
connection-timeout = 5000
read-timeout = 30000
haproxy-protocol = false
tcp-fast-open = true
bungee-plugin-message-channel = true
show-ping-requests = false
failover-on-unexpected-server-disconnect = true
announce-proxy-commands = true
log-command-executions = false
log-player-connections = true
[query]
enabled = true
port = 25577
map = "Velocity Network"
show-plugins = false
Velocity Installation:
#!/bin/bash
# install-velocity.sh
VELOCITY_VERSION="3.2.0-SNAPSHOT"
VELOCITY_DIR="/opt/minecraft/velocity"
mkdir -p "$VELOCITY_DIR"
cd "$VELOCITY_DIR"
# Download Velocity
wget -O velocity.jar "https://api.papermc.io/v2/projects/velocity/versions/${VELOCITY_VERSION}/builds/latest/downloads/velocity-${VELOCITY_VERSION}-latest.jar"
# Create startup script
cat > start.sh <<EOF
#!/bin/bash
java -Xms512M -Xmx512M -XX:+UseG1GC -jar velocity.jar
EOF
chmod +x start.sh
Multi-Server Network Setup
Network Architecture:
Internet
↓
Load Balancer
(Optional)
↓
Velocity Proxy
(Port 25565)
↓
┌──────────────┼──────────────┐
↓ ↓ ↓
Lobby Server Game Server 1 Game Server 2
(4GB RAM) (8GB RAM) (8GB RAM)
Server Allocation:
- Lobby: 4GB RAM, 2 CPU cores (lightweight, many players)
- Game Servers: 8GB RAM, 4 CPU cores each (resource-intensive)
- Velocity Proxy: 1GB RAM, 1 CPU core (low resource usage)
Security and Protection
DDoS Protection
Minecraft servers are frequent DDoS targets. Implement protection:
# Install fail2ban
apt install -y fail2ban
# Configure fail2ban for Minecraft
cat > /etc/fail2ban/jail.local <<EOF
[minecraft]
enabled = true
port = 25565
filter = minecraft
logpath = /opt/minecraft/server/logs/latest.log
maxretry = 5
bantime = 3600
EOF
cat > /etc/fail2ban/filter.d/minecraft.conf <<EOF
[Definition]
failregex = ^.*\[.*\]: <.*> lost connection: Disconnected
^.*\[.*\]: <.*> lost connection: Timed out
ignoreregex =
EOF
systemctl restart fail2ban
Firewall Hardening
# Allow only necessary ports
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 25565/tcp
ufw enable
# Rate limit connections
iptables -A INPUT -p tcp --dport 25565 -m connlimit --connlimit-above 10 -j REJECT
Plugin Security
Recommended Security Plugins:
- AuthMe: Password authentication
- AntiVPN: Block VPN connections
- AdvancedBan: Ban management
- CoreProtect: Logging and rollback
SEO Optimization for Minecraft Hosting
Target Keywords
Primary Keywords:
- minecraft hosting
- minecraft vds
- minecraft server hosting
- cheap minecraft hosting
- minecraft server vps
Long-Tail Keywords:
- best minecraft hosting 2025
- minecraft server hosting with mods
- minecraft hosting with plugins
- minecraft vps hosting europe
Content Strategy
Create SEO-optimized content:
- Server setup guides
- Plugin installation tutorials
- Performance optimization guides
- Multi-server network setup guides
FAQ
What are the minimum server requirements for 50 players?
Minimum Requirements:
- RAM: 6-8GB
- CPU: 4 cores (2.5+ GHz)
- Storage: 50GB SSD
- Bandwidth: 50 Mbps
Recommended Requirements:
- RAM: 8-12GB
- CPU: 4-6 cores (3.0+ GHz)
- Storage: 100GB NVMe SSD
- Bandwidth: 100 Mbps
How do I optimize TPS on a laggy server?
- Reduce view distance: Set
view-distance=10in server.properties - Limit entities: Use Paper's entity-per-chunk limits
- Optimize JVM: Use Aikar's flags for G1GC
- Update plugins: Remove or update outdated plugins
- Pre-generate world: Use WorldBorder plugin to pre-generate chunks
- Monitor with timings: Use
/timings reportto identify bottlenecks
Should I use BungeeCord or Velocity?
Choose Velocity if:
- You're using Paper/Spigot 1.13+
- You want maximum performance
- You need modern plugin support
Choose BungeeCord if:
- You're using older server versions
- You need specific BungeeCord plugins
- You prefer more established ecosystem
How do I prevent server crashes?
- Proper JVM flags: Use recommended memory and GC settings
- Regular backups: Automated backups every 6 hours
- Plugin updates: Keep plugins updated
- Monitor logs: Check for errors and warnings
- Resource limits: Set proper CPU and memory limits
- Auto-restart: Use systemd or screen with auto-restart script
Can I host multiple Minecraft servers on one VPS?
Yes, but allocate resources carefully:
- 2 servers (50 players each): 12GB RAM, 6 CPU cores
- 3 servers (25 players each): 12GB RAM, 6 CPU cores
- 4+ servers: Consider dedicated servers or multiple VPS instances
Use Velocity/BungeeCord to connect servers and balance load.
What is the best server software for performance?
Paper is recommended for most use cases:
- Best performance (50-80% improvement over Vanilla)
- Active development
- Large plugin ecosystem
- Easy configuration
Purpur offers even better performance but with more configuration complexity.
Conclusion
Minecraft server hosting requires understanding Java performance, server software optimization, and scaling strategies. Paper/Purpur servers with optimized JVM settings can handle 100+ players on a single VPS, while Velocity proxy enables multi-server networks for thousands of players.
Key takeaways:
- Java tuning is critical: Use G1GC with Aikar's flags
- Paper/Purpur offer 50-100% performance improvement over Vanilla
- View distance has the biggest impact on performance
- Velocity is superior to BungeeCord for modern deployments
- Monitoring TPS and memory usage prevents crashes
For production Minecraft hosting, bulletproof infrastructure from Dior Host ensures servers remain online even under high player loads and DDoS attacks. Our VPS hosting and VDS hosting provide the CPU, RAM, and bandwidth required for high-performance Minecraft servers.
Ready to host your Minecraft server?
Dior Host offers high-performance VDS hosting optimized for Minecraft servers. Our infrastructure provides the CPU, RAM, and bandwidth required for 100+ player servers with stable 20 TPS performance.
Explore VDS plans for Minecraft hosting → | View VPS options → | Minecraft hosting support →