Minecraft Server Performance Optimization Guide
Is your Minecraft server lagging? Players rubberbanding? TPS dropping below 20? This guide covers every optimization technique available to squeeze maximum performance from your Java Edition server.
Why Optimization Matters
A Minecraft server runs on a single main thread that processes the entire game world 20 times per second. Each of these cycles is called a tick, and the server has exactly 50 milliseconds to complete each one.
Understanding TPS and MSPT
| Metric | Meaning | Ideal Value | Warning Threshold |
|---|---|---|---|
| TPS | Ticks Per Second | 20.0 | Below 18.0 |
| MSPT | Milliseconds Per Tick | Under 50ms | Over 50ms |
- >TPS 20.0 - Server is running perfectly, all ticks complete within 50ms
- >TPS 15-19 - Noticeable lag, some game mechanics slow down
- >TPS 10-14 - Significant lag, mob AI stutters, block interactions delay
- >TPS below 10 - Severely degraded, nearly unplayable
Types of Lag
Server-side lag (low TPS):
- >Caused by too many entities, chunk loading, plugins, or world generation
- >Affects all players equally
- >Solved by the optimizations in this guide
- >Caused by the player's hardware, shaders, or render distance
- >Only affects the individual player
- >Not something server admins can fix directly
- >Caused by distance between player and server, or poor routing
- >Results in delayed block placement and rubberbanding
- >Solved with better hosting or proximity to players
Step 1: Choose the Right Server Software
The single most impactful optimization you can make is choosing the right server software. Vanilla Minecraft server is not designed for performance.
Server Software Comparison
| Software | Performance | Plugin Support | Mod Support | Best For |
|---|---|---|---|---|
| Vanilla | Baseline | None | None | Testing only |
| CraftBukkit | Slight improvement | Bukkit API | None | Legacy, not recommended |
| Spigot | Moderate | Bukkit + Spigot API | None | Small servers |
| Paper | Excellent | Bukkit + Spigot + Paper API | None | Most servers (recommended) |
| Purpur | Excellent | Full Paper compatibility | None | Servers wanting extra features |
| Folia | Best (multi-threaded) | Limited (region-based) | None | Large-scale, experimental |
| Fabric | Good | Fabric mods only | Fabric mods | Lightweight modded servers |
| Forge | Moderate | Forge mods only | Forge mods | Modded servers |
Why Paper is Recommended
Paper is the gold standard for most Minecraft servers because it:
- >Provides 2-3x better performance over vanilla through extensive patches
- >Maintains full Spigot and Bukkit plugin compatibility
- >Offers async chunk loading out of the box
- >Includes additional configuration options for fine-tuning
- >Has an active development community with frequent updates
- >Fixes many vanilla bugs and exploits
Installing Paper
server.jar with the Paper jar# Download Paper (check papermc.io for the latest build)
curl -o paper.jar https://api.papermc.io/v2/projects/paper/versions/1.21.4/builds/LATEST/downloads/paper-1.21.4-LATEST.jar
# Start with Paper
java -jar paper.jar nogui
Your existing world data, plugins, and configurations will work with Paper without modification.
About Folia
Folia is Paper's experimental multi-threaded server. Instead of running everything on one thread, Folia splits the world into independent regions that tick in parallel.
Folia is ideal for:
- >Servers with 200+ concurrent players
- >Massive survival worlds with spread-out players
- >Situations where single-threaded performance is the bottleneck
- >Most plugins (they need Folia-specific updates)
- >Servers with fewer than 50 players
- >Servers that rely on many plugins
Step 2: JVM Startup Flags
Java Virtual Machine (JVM) flags control how Minecraft uses memory and handles garbage collection. The right flags can dramatically reduce lag spikes.
Aikar's Flags (The Gold Standard)
Aikar's flags are the most widely tested and recommended JVM flags for Minecraft servers. They optimize the G1 garbage collector to minimize pause times during gameplay.
Full recommended startup command:
java -Xms10G -Xmx10G -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
Flags Explained
Memory allocation:
-Xms10G # Starting heap size (set equal to Xmx)
-Xmx10G # Maximum heap size
- >Always set
-Xmsand-Xmxto the same value to prevent heap resizing - >Never allocate more than 75% of your total system RAM
- >Do not allocate more than you need; excess memory leads to longer GC pauses
| Server Type | Players | Recommended RAM |
|---|---|---|
| Vanilla / Paper (small) | 1-10 | 4-6 GB |
| Paper with plugins | 10-30 | 6-10 GB |
| Paper with many plugins | 30-50 | 10-12 GB |
| Heavy modded (Forge) | 5-20 | 8-16 GB |
| Large network (50+) | 50-100 | 12-16 GB |
| Flag | Purpose |
|---|---|
-XX:+UseG1GC | Use the G1 garbage collector (best for Minecraft) |
-XX:+ParallelRefProcEnabled | Process references in parallel to reduce pause time |
-XX:MaxGCPauseMillis=200 | Target maximum GC pause of 200ms |
-XX:+DisableExplicitGC | Prevent plugins from forcing full GC pauses |
-XX:+AlwaysPreTouch | Pre-allocate memory pages at startup |
-XX:G1NewSizePercent=30 | Reserve 30% of heap for new objects |
-XX:G1MaxNewSizePercent=40 | Cap new generation at 40% of heap |
-XX:G1HeapRegionSize=8M | Set G1 region size for efficient collection |
-XX:G1ReservePercent=20 | Reserve 20% heap to prevent promotion failure |
-XX:InitiatingHeapOccupancyPercent=15 | Start concurrent GC early to avoid full pauses |
-XX:SurvivorRatio=32 | Minimize survivor space since Minecraft has few mid-lived objects |
-XX:MaxTenuringThreshold=1 | Promote objects to old generation quickly |
-XX:+PerfDisableSharedMem | Prevent GC pauses from disk I/O |
Linux Startup Script
Create a start.sh file:
#!/bin/bash
java -Xms10G -Xmx10G \
-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
chmod +x start.sh
./start.sh
Windows Startup Script
Create a start.bat file:
@echo off
java -Xms10G -Xmx10G -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
pause
---
Step 3: server.properties Optimization
These settings are in the standard server.properties file and apply to all server software.
# View distance - chunks sent to clients (default: 10)
# Lower = less chunk data to process and send
view-distance=7
# Simulation distance - chunks that are actively ticked (default: 10)
# Controls entity AI, block updates, redstone within this range
simulation-distance=5
# Network compression threshold in bytes (default: 256)
# Set to 512 to reduce CPU usage from compression, or -1 to disable
network-compression-threshold=256
# Max tick time before watchdog kills server (default: 60000)
# Set to -1 to disable watchdog (useful for heavy world gen)
max-tick-time=60000
# Rate limiting - prevent spam flooding
rate-limit=0
# Sync chunk writes - disable for SSD performance boost
sync-chunk-writes=false
View Distance vs Simulation Distance
Understanding the difference between these two is critical for optimization:
| Setting | What It Controls | Performance Impact |
|---|---|---|
view-distance | How many chunks are visible to players | Moderate (network + memory) |
simulation-distance | How many chunks are actively ticked | High (CPU-intensive) |
| Server Size | view-distance | simulation-distance |
|---|---|---|
| 1-10 players | 8-10 | 5-6 |
| 10-30 players | 6-8 | 4-5 |
| 30-50 players | 5-7 | 3-4 |
| 50+ players | 4-6 | 3-4 |
simulation-distance lower than view-distance lets players see far while keeping CPU usage manageable. Players will see distant chunks but mobs and redstone will only function within the simulation distance.---
Step 4: Paper-Specific Configuration
Paper introduces several configuration files with hundreds of tunable options. These are the most impactful settings.
paper-global.yml
Located at config/paper-global.yml:
# Chunk loading configuration
chunk-loading-basic:
# Automatically set based on CPU cores
autoconfig-send-distance: true
# Players loaded per tick (lower = smoother loading)
player-max-chunk-load-rate: -1.0
player-max-concurrent-chunk-loads: 0.0
player-max-concurrent-chunk-generates: 0.0
# Async chunk configuration
chunk-loading-advanced:
auto-config-send-distance: true
player-max-concurrent-chunk-loads: 0.0
player-max-concurrent-chunk-generates: 0.0
# Packet limiter (prevent exploit-based lag)
packet-limiter:
kick-message: '<red><lang:disconnect.exceeded_packet_rate>'
limits:
all:
action: KICK
interval: 7.0
max-packet-rate: 500.0
ServerboundPlaceRecipePacket:
action: DROP
interval: 4.0
max-packet-rate: 5.0
# Watchdog settings
watchdog:
early-warning-delay: 10000
early-warning-every: 5000
paper-world-defaults.yml
Located at config/paper-world-defaults.yml. These settings have the highest impact on performance:
chunks:
# Delay before unloading unused chunks (default: 10s)
delay-chunk-unloads-by: 10s
# Maximum auto-save rate for chunks
max-auto-save-chunks-per-tick: 24
# Prevent moving into unloaded chunks
prevent-moving-into-unloaded-chunks: true
entities:
# Limit entities saved per chunk to prevent corruption lag
entity-per-chunk-save-limit:
arrow: 16
ender_pearl: 8
experience_orb: 16
fireball: 8
small_fireball: 8
snowball: 8
behavior:
# Disable pillager patrols if not needed
pillager-patrols:
disable: false
spawn-chance: 0.2
spawn-delay:
per-player: true
ticks: 12000
# Zombie villager cure time
zombie-villager-infection-chance: -1.0
spawn-limits:
# Reduce ambient mobs (bats)
ambient: 1
# Reduce total monster cap
monster: 50
# Reduce water mobs
water-ambient: 2
water-animal: 2
water-underground-creature: 3
creature: 8
axolotls: 3
underground-water-creature: 3
# Mob spawner settings
tick-rates:
# How often mob spawners check for spawn conditions
mob-spawner: 2
# Sensor and behavior tick rates for mobs
sensor:
villager:
secondarypoisensor: 80
behavior:
villager:
validatenearbypoi: 60
# Explosion optimization
environment:
optimize-explosions: true
treasure-maps:
enabled: true
find-already-discovered:
loot-tables: default
villager-trade: false
# Hopper optimization
hopper:
cooldown-when-full: true
disable-move-event: false
ignore-occluding-blocks: false
# Collisions
collisions:
# Limit entity collision checks
max-entity-collisions: 2
# Fix TNT entity clipping
fix-climbing-bypassing-cramming-rule: true
# Misc optimizations
misc:
# Reduce armor stand tick rate
armor-stands:
do-collision-entity-lookups: false
tick: false
# Redstone optimization
redstone-implementation: ALTERNATE_CURRENT
# Update pathfinding on block changes
update-pathfinding-on-block-update: false
Key Paper Optimizations Explained
| Setting | What It Does | Impact |
|---|---|---|
entity-per-chunk-save-limit | Caps saved entities to prevent lag on chunk load | High |
optimize-explosions | Uses optimized explosion algorithm | Medium |
mob-spawner tick rate | Slows spawner checks (2 = every other tick) | Medium |
redstone-implementation: ALTERNATE_CURRENT | Uses a faster redstone algorithm | High |
armor-stands.tick: false | Stops ticking armor stands | Medium |
max-entity-collisions: 2 | Limits collision processing per entity | Medium |
hopper.cooldown-when-full: true | Stops hoppers from checking when full | High |
update-pathfinding-on-block-update: false | Reduces pathfinding recalculations | Medium |
Step 5: spigot.yml Optimization
Paper inherits Spigot's configuration. These settings are in spigot.yml:
world-settings:
default:
# Entity activation range - mobs outside these ranges have reduced AI
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
water: 8
villagers: 24
flying-monsters: 48
villagers-work-immunity-after: 100
villagers-work-immunity-for: 20
villagers-active-for-panic: true
tick-inactive-villagers: true
wake-up-inactive:
animals-max-per-tick: 4
animals-every: 1200
animals-for: 100
monsters-max-per-tick: 8
monsters-every: 400
monsters-for: 100
villagers-max-per-tick: 4
villagers-every: 600
villagers-for: 100
flying-monsters-max-per-tick: 8
flying-monsters-every: 200
flying-monsters-for: 100
# Merge radius - combine nearby items and XP orbs
merge-radius:
item: 4.0
exp: 6.0
# Mob spawn range (in chunks)
mob-spawn-range: 6
# Growth rates (higher = slower growth, saves performance)
growth:
cactus-modifier: 100
cane-modifier: 100
melon-modifier: 100
mushroom-modifier: 100
pumpkin-modifier: 100
sapling-modifier: 100
beetroot-modifier: 100
carrot-modifier: 100
potato-modifier: 100
wheat-modifier: 100
# Item despawn rates (in ticks, 6000 = 5 minutes)
item-despawn-rate: 6000
# Arrow despawn rate
arrow-despawn-rate: 300
# Nerf spawner mobs (remove AI from spawner-created mobs)
nerf-spawner-mobs: false
# Ticks per animal/monster spawn cycle
ticks-per:
animal-spawns: 400
monster-spawns: 1
autosave: 6000
Key Spigot Optimizations
| Setting | Default | Optimized | Effect |
|---|---|---|---|
entity-activation-range.animals | 32 | 16 | Animals further away run minimal AI |
entity-activation-range.monsters | 32 | 24 | Monsters have reduced AI at distance |
merge-radius.item | 2.5 | 4.0 | Items merge from further away, fewer entities |
merge-radius.exp | 3.0 | 6.0 | XP orbs merge aggressively |
mob-spawn-range | 8 | 6 | Mobs spawn closer, despawn faster further out |
arrow-despawn-rate | 1200 | 300 | Arrows clean up faster |
ticks-per.animal-spawns | 400 | 400 | Keep default, animals are cheap |
ticks-per.monster-spawns | 1 | 1 | Keep default, Paper handles this better |
Step 6: bukkit.yml Optimization
The bukkit.yml file controls fundamental server behavior:
spawn-limits:
# Maximum mobs per world
monsters: 50
animals: 8
water-animals: 3
water-ambient: 2
water-underground-creature: 3
axolotls: 3
ambient: 1
chunk-gc:
# Period in ticks between chunk garbage collection (default: 400)
period-in-ticks: 400
ticks-per:
# How often the server attempts to spawn each mob type
animal-spawns: 400
monster-spawns: 1
water-spawns: 1
water-ambient-spawns: 1
water-underground-creature-spawns: 1
axolotl-spawns: 1
ambient-spawns: 1
autosave: 6000
Spawn Limits Breakdown
The default mob caps are often too generous. Reducing them directly lowers entity count and tick times:
| Mob Type | Vanilla Default | Optimized | Notes |
|---|---|---|---|
monsters | 70 | 50 | Largest performance impact |
animals | 10 | 8 | Slight reduction, barely noticeable |
water-animals | 5 | 3 | Dolphins, squids |
water-ambient | 20 | 2 | Tropical fish, huge default |
ambient | 15 | 1 | Bats, rarely noticed by players |
Step 7: Pre-Generating Chunks
Chunk generation is one of the most CPU-intensive operations. When players explore new areas, the server must generate terrain, structures, caves, and biomes in real-time. Pre-generating chunks eliminates this lag entirely.
Using Chunky Plugin
Chunky is the recommended pre-generation plugin for Paper servers.
Installation:
.jar in your plugins/ folderBasic usage:
# Set the world to pre-generate
/chunky world overworld
# Set the center point (usually spawn)
/chunky center 0 0
# Set the radius in blocks
/chunky radius 5000
# Set the shape (square or circle)
/chunky shape circle
# Start pre-generation
/chunky start
# Monitor progress
/chunky progress
# Pause if needed
/chunky pause
# Resume
/chunky continue
# Cancel
/chunky cancel
Recommended pre-generation sizes:
| Server Type | Radius | Approx Chunks | Time Estimate |
|---|---|---|---|
| Small survival | 3000 blocks | ~14,000 | 15-30 min |
| Medium survival | 5000 blocks | ~39,000 | 45-90 min |
| Large survival | 10000 blocks | ~156,000 | 3-6 hours |
| World border limit | 15000 blocks | ~352,000 | 8-15 hours |
- >Run during off-peak hours or before the server goes public
- >Pre-generate all dimensions: overworld, nether, and end
- >Set a world border to prevent further generation:
/worldborder center 0 0
/worldborder set 10000
---
Step 8: Essential Performance Plugins
Spark (Profiling)
Spark is the most important performance tool for any server admin. It profiles your server and identifies exactly what is causing lag.
Installation: Download from Modrinth or SpigotMC
Key commands:
# View current TPS and tick durations
/spark tps
# Start a profiler for 60 seconds
/spark profiler --timeout 60
# Profile only the server thread
/spark profiler --thread Server
# View memory usage
/spark health
# Generate a heap dump (for memory leak investigation)
/spark heapdump
Spark generates a shareable web report. The flame graph shows exactly which methods consume the most tick time, helping you pinpoint problematic plugins, entities, or game mechanics.
Chunky (Pre-generation)
Covered in Step 7. Essential for any survival server to eliminate chunk generation lag.
ViewDistanceTweaks
Dynamically adjusts view distance per player based on current server performance.
How it works:
- >When TPS is high, players get full view distance
- >When TPS drops, view distance is automatically reduced
- >Each player can have a different view distance
# ViewDistanceTweaks config.yml
enabled: true
proactive-mode-settings:
# Target MSPT to maintain
target-mspt: 40.0
# Increase view distance when MSPT is this low
increase-mspt-threshold: 30.0
# How many chunks to change at a time
change-amount: 1
# Check interval in ticks
check-interval: 40
# Minimum view distance
minimum-view-distance: 4
# Maximum view distance
maximum-view-distance: 12
EntityDetection
Helps find chunk areas with excessive entities that are dragging down TPS.
Usage:
# Scan for chunks with many entities
/ed scan
# Show top chunks by entity count
/ed top 10
# Teleport to a problematic chunk
/ed tp <chunk>
---
Monitoring Performance
In-Game Monitoring
TPS check:
# Paper built-in
/mspt
# Spark plugin
/spark tps
The /mspt command shows tick timing over the last 5 seconds, 1 minute, and 5 minutes. Each value should be under 50ms.
Example good output:
Server tick times (avg/min/max) from last 5s, 10s, 60s:
◆ 12.5/10.2/15.8, 13.1/9.8/18.2, 14.2/8.5/22.1
Example bad output:
Server tick times (avg/min/max) from last 5s, 10s, 60s:
◆ 52.3/45.1/68.9, 55.8/42.3/78.2, 48.7/35.2/95.1
Using Spark Profiler
For a detailed performance breakdown:
/spark profiler --timeout 300 during normal gameplayWhat to look for in Spark reports:
| Category | Meaning | Action |
|---|---|---|
net.minecraft.server.level.ServerLevel.tick | World ticking | Check entity counts, reduce simulation distance |
net.minecraft.world.entity | Entity processing | Reduce mob caps, increase activation ranges |
net.minecraft.world.level.chunk | Chunk operations | Pre-generate, reduce view distance |
| Plugin class names | Plugin overhead | Optimize or replace laggy plugins |
java.lang.Thread.sleep | Idle time (good) | Server has headroom |
Common Performance Killers and Fixes
1. Too Many Entities
Symptoms: Low TPS, high entity tick time in Spark
Fixes:
- >Reduce
spawn-limitsinbukkit.yml - >Lower
entity-activation-rangeinspigot.yml - >Set
entity-per-chunk-save-limitin Paper config - >Kill excessive mobs:
/kill @e[type=zombie,distance=..100] - >Use entity-limiting plugins for farms
2. Unoptimized Redstone
Symptoms: Lag near redstone contraptions
Fixes:
- >Set
redstone-implementation: ALTERNATE_CURRENTin Paper config - >Ask players to optimize or limit redstone machines
- >Consider a redstone tick limiter plugin
3. Chunk Generation Lag
Symptoms: TPS drops when players explore new areas
Fixes:
- >Pre-generate with Chunky (Step 7)
- >Set a world border to limit exploration
- >Reduce view distance
4. Hopper Lag
Symptoms: TPS drops near large hopper systems
Fixes:
- >Set
hopper.cooldown-when-full: truein Paper config - >Encourage players to use water streams instead of long hopper chains
- >Limit hopper count per chunk
5. Villager AI
Symptoms: Lag near large villager trading halls
Fixes:
- >Reduce
entity-activation-range.villagersinspigot.yml - >Set
tick-inactive-villagers: falseinspigot.yml(may break iron farms) - >Limit villager counts per area
- >Increase villager sensor tick rates in Paper config
6. Excessive Plugins
Symptoms: High MSPT, plugin methods appearing in Spark reports
Fixes:
- >Profile with Spark to identify the culprits
- >Remove unused plugins
- >Replace heavy plugins with lighter alternatives
- >Avoid plugins that run tasks every tick
7. Insufficient RAM or Swap Usage
Symptoms: Periodic lag spikes, high GC time in Spark
Fixes:
- >Increase
-Xmsand-Xmxvalues - >Make sure Aikar's flags are applied correctly
- >Ensure the system has enough free RAM beyond the JVM allocation
- >Disable swap on the server host if possible
Hardware Recommendations
Server Hardware Guide
| Component | Budget | Mid-Range | High-End |
|---|---|---|---|
| CPU | Intel i5 / Ryzen 5 (4 cores) | Intel i7 / Ryzen 7 (8 cores) | Intel i9 / Ryzen 9 (12+ cores) |
| Single-Core Speed | 3.5+ GHz | 4.0+ GHz | 5.0+ GHz |
| RAM | 8 GB DDR4 | 16 GB DDR4/DDR5 | 32-64 GB DDR5 |
| Storage | 256 GB SSD | 500 GB NVMe SSD | 1 TB NVMe SSD |
| Network | 100 Mbps | 1 Gbps | 1-10 Gbps |
| Players Supported | 10-20 | 20-50 | 50-200+ |
Key Hardware Priorities
VPS / Dedicated Hosting
When choosing a hosting provider, prioritize:
- >CPU clock speed over core count
- >NVMe SSD over HDD or SATA SSD
- >DDR4/DDR5 RAM with sufficient allocation
- >Low geographic latency to your player base
- >DDoS protection for public servers
Optimization Checklist
Use this checklist to verify you have applied all optimizations:
- >[ ] Running Paper (or Purpur) server software
- >[ ] Aikar's JVM flags applied in startup script
- >[ ]
-Xmsand-Xmxset to the same value - >[ ]
view-distancereduced to 6-10 - >[ ]
simulation-distancereduced to 4-6 - >[ ]
sync-chunk-writesset tofalse - >[ ] Paper
redstone-implementationset toALTERNATE_CURRENT - >[ ] Paper
optimize-explosionsset totrue - >[ ] Paper
entity-per-chunk-save-limitconfigured - >[ ] Paper
armor-stands.tickset tofalse - >[ ] Paper
hopper.cooldown-when-fullset totrue - >[ ] Paper
max-entity-collisionsreduced to 2 - >[ ] Spigot
entity-activation-rangetuned - >[ ] Spigot
merge-radiusincreased - >[ ] Bukkit
spawn-limitsreduced - >[ ] Chunks pre-generated with Chunky
- >[ ] World border set
- >[ ] Spark installed for monitoring
- >[ ] Regular performance profiling scheduled
Conclusion
Server optimization is an ongoing process, not a one-time task. Start by switching to Paper and applying Aikar's flags for the biggest immediate improvement. Then work through the configuration files, reducing mob caps and entity processing. Pre-generate your world with Chunky and install Spark to monitor performance continuously.
Priority order for maximum impact:
Remember: Every server is different. What works for a 10-player survival server may not apply to a 100-player minigame network. Use Spark to profile your specific setup and make data-driven decisions.