How to Optimize Your Minecraft Server for Maximum Performance
Table of Contents
How to Optimize Your Minecraft Server for Maximum Performance
You’ve got your Minecraft server running, players are joining, and everything seems fine — until 20 people get online and TPS drops to 14. Blocks take a second to break. Mobs stutter. Chat has a delay. Sound familiar?
Server optimization is the difference between a server that struggles at 15 players and one that handles 50 smoothly on the same hardware. This guide covers the specific, technical changes that make the biggest impact.
Step 0: Use the Right Server Software
If you’re running vanilla Mojang server software, stop. Switch to Paper or Purpur before doing anything else. This single change will have a bigger impact than every other optimization in this guide combined.
Paper is a high-performance fork of Spigot that includes dozens of optimizations to chunk loading, entity processing, hoppers, redstone, and more. It’s compatible with all Bukkit and Spigot plugins.
Purpur is a fork of Paper with even more configuration options and performance tweaks. It adds features that Paper considers too niche to include by default.
Both are drop-in replacements. Download the jar, replace your existing server jar, and start. Your world, plugins, and configurations carry over.
Step 1: View Distance and Simulation Distance
These two settings have the single biggest impact on performance after choosing server software.
View Distance
view-distance in server.properties controls how many chunks around each player are sent to their client. Default is 10 (21x21 chunk area per player).
Every chunk sent to a player consumes:
- Server RAM (chunk data must be loaded)
- CPU (chunks must be processed)
- Network bandwidth (chunk data must be transmitted)
Multiply this by your player count, and the numbers get large fast.
Recommended values:
- Vanilla/semi-vanilla, <20 players: 8-10
- Plugins, 20-40 players: 6-8
- Heavy plugins or 40+ players: 5-6
- Modded servers: 6-8
Players may complain about reduced view distance. The trade-off is smooth gameplay versus seeing distant terrain. Smooth gameplay wins.
Simulation Distance
simulation-distance in server.properties (1.18+) controls how far from players entities are ticked (mobs move, hoppers process, redstone fires, crops grow). This is separate from view distance.
Setting simulation distance lower than view distance means players can see distant chunks but entities in those chunks are “frozen” — no CPU cost.
Recommended: Set simulation distance 2-4 chunks lower than view distance. Example: view-distance=8, simulation-distance=5.
Step 2: Paper Configuration
Paper’s configuration files (paper-global.yml and paper-world-defaults.yml) contain dozens of performance-relevant settings. Here are the most impactful ones.
paper-global.yml
chunk-loading-basic:
player-max-chunk-load-rate: 100.0
player-max-concurrent-chunk-loads: 4.0
These limit how fast chunks load per player, preventing chunk loading from overwhelming the server when many players move simultaneously.
paper-world-defaults.yml
Entity activation range — controls the distance at which entities are fully ticked:
entity-activation-range:
animals: 16
monsters: 24
raiders: 48
misc: 8
water: 8
villagers: 16
flying-monsters: 32
Entities outside their activation range use simplified AI — they exist but don’t run expensive pathfinding, targeting, or behavior logic. Reducing these values significantly cuts CPU usage.
Default is conservative. You can safely reduce most of these by 25-50% without players noticing, especially animals and misc.
Hopper optimization:
hopper:
cooldown-when-full: true
disable-move-event: false
ignore-occluding-blocks: false
Hoppers are one of the most expensive blocks in Minecraft. Each hopper checks for items above it every tick. Set cooldown-when-full: true to prevent hoppers from ticking when they can’t accept items.
If you don’t have plugins that interact with hopper events (most servers don’t), set disable-move-event: true for a significant performance boost with hopper-heavy builds.
Mob spawning:
spawn-limits:
ambient: 1
axolotls: 3
creature: 5
monster: 30
underground-water-creature: 3
water-ambient: 2
water-creature: 2
Default vanilla mob caps are generous. Reducing creature (passive mob) spawns has almost no gameplay impact but reduces entity count significantly. Ambient (bats) can be set to 1 or even 0 without anyone noticing.
Merge radius:
merge-radius:
exp: 6.0
item: 4.0
Increasing merge radius causes dropped items and experience orbs to merge from further away, reducing entity count on the ground. Especially useful during mob grinder activity.
Step 3: Purpur-Specific Optimizations
If you’re running Purpur, you get additional knobs to turn.
purpur.yml
Villager optimization — villagers are notoriously expensive:
villager:
brain-ticks: 2
spawn-iron-golem:
radius: 0
brain-ticks: 2 makes villagers think every 2 ticks instead of every tick. This halves villager CPU cost with negligible behavior changes. You can go up to 3-4 if you have large villager populations.
Entity limits per chunk:
entity-limits:
axolotls: 5
villager: 8
Hard caps on how many of each entity type can exist in a single chunk. Prevents farms and breeders from creating entity count explosions.
Step 4: Pre-Generate Your World
World generation is the most CPU-intensive operation in Minecraft. When a player walks into ungenerated territory, the server must:
- Run the terrain generator
- Apply biome placement
- Generate structures
- Populate with ores, vegetation, mobs
- Light the chunks
All of this happens on the main thread, causing TPS drops for everyone on the server.
Solution: pre-generate the world before players join.
Install the Chunky plugin:
/chunky radius 5000
/chunky start
This generates all chunks within a 5000-block radius of spawn. On a decent server, this takes 1-4 hours depending on the radius and world complexity.
When to pre-generate:
- Before opening a new world
- After a world reset
- When expanding your world border
Set a world border at or slightly beyond your pre-generated area to prevent players from triggering chunk generation.
Step 5: Garbage Collection Tuning
Minecraft servers run on Java, and Java uses garbage collection (GC) to manage memory. Poor GC configuration causes lag spikes — momentary freezes when the JVM pauses to clean up unused memory.
Aikar’s Flags
The community-standard JVM flags for Minecraft, developed and tested by Aikar (a PaperMC developer):
java -Xms8G -Xmx8G -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:G1MixedGCCountTarget=4
-XX:InitiatingHeapOccupancyPercent=15
-XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1
-jar server.jar nogui
Important notes:
- Set
-Xmsand-Xmxto the same value. This pre-allocates memory and avoids heap resizing. - Adjust the memory values to match your plan’s allocation minus ~500MB for overhead (if your plan is 8GB, use
-Xms7G -Xmx7G). - These flags are designed for G1GC, which is the recommended garbage collector for Minecraft.
Most hosting providers, including Witchly, allow you to set custom startup flags through the panel.
Step 6: Use Spark to Profile Your Server
Guessing at performance problems wastes time. Spark is a profiler designed specifically for Minecraft servers that tells you exactly what’s consuming your resources.
Install Spark as a plugin, then:
/spark profiler start
Wait 5-10 minutes during normal gameplay, then:
/spark profiler stop
Spark generates a detailed web report showing:
- What’s using CPU: Broken down by plugin, game mechanic, and function. You’ll see exactly which plugin or system is consuming the most processing time.
- Tick duration breakdown: How long each tick takes and what fills that time.
- Garbage collection stats: How often GC runs and how long it pauses the server.
- Thread analysis: What each thread is doing.
Reading Spark Reports
The most common findings:
- A specific plugin dominating CPU: If one plugin uses 30%+ of tick time, it’s either poorly coded or misconfigured. Check for updates, configuration optimizations, or consider alternatives.
- Entity ticking taking too long: Too many entities in loaded chunks. Reduce spawn limits, add entity activation range limits, or use a mob stacking plugin.
- Chunk generation: Players exploring ungenerated areas. Pre-generate with Chunky.
- Hopper processing: Large hopper systems tick every game tick. Use Paper’s hopper optimizations.
Step 7: Identify and Replace Lag-Causing Plugins
Not all plugins are created equal. Some common culprits:
Known Performance-Heavy Plugins
- Dynmap: Rendering a live map is extremely I/O and CPU intensive. If you must use it, limit render distance, increase render interval, and consider BlueMap as a lighter alternative.
- ClearLag: Ironically, this “anti-lag” plugin can cause lag. Its entity scanning and removal cycles consume CPU. Paper’s built-in optimizations handle most of what ClearLag does.
- EssentialsX spawn/kit features with slow storage: If EssentialsX uses flat-file storage with thousands of player files, operations slow down. Consider a database backend.
- Citizens/NPC plugins with many NPCs: Each NPC is a full entity. 50+ NPCs in a small area will impact performance.
- World editing plugins during use: WorldEdit and FAWE are fine to have installed but cause massive lag during large operations. Limit operation sizes and perform edits during low-population periods.
How to Test Plugin Impact
- Profile with Spark (baseline)
- Remove the suspected plugin
- Profile again
- Compare the reports
If removing a plugin improves TPS significantly, you’ve found your culprit. Look for a better alternative or optimize its configuration.
Step 8: Entity and Tile Entity Management
Entities (mobs, items, arrows, experience orbs) and tile entities (hoppers, furnaces, chests, signs) are the two biggest performance sinks in Minecraft.
Reduce Entity Count
- Lower spawn limits in Paper configuration
- Set a world border to limit spawnable area
- Use entity activation range settings aggressively
- Increase item and XP merge radius
- Set arrow despawn rate lower (Paper config:
non-player-arrow-despawn-rate) - Limit mob farm output with hopper-based collection instead of ground items
Manage Tile Entities
- Hoppers: Minimize hopper chains. Use water streams to move items instead where possible.
- Redstone: Constant redstone clocks tick every game tick. Encourage players to use observer-based designs instead of repeater clocks.
- Chunk loaders: If using a chunk loader plugin, limit the number of force-loaded chunks. Each loaded chunk ticks all entities and tile entities within it.
Step 9: Monitor Continuously
Optimization isn’t a one-time task. As your server grows, new plugins are added, and player behavior evolves, new performance issues will emerge.
Weekly routine:
- Check average TPS over the past week
- Look at RAM usage trends (is baseline climbing?)
- Check entity counts (are they growing over time?)
- Review Spark profiles if TPS dipped below 18
Monthly routine:
- Update all plugins and server software
- Audit installed plugins (remove any you’re not using)
- Review world size and chunk count
- Check for available Paper/Purpur updates with performance improvements
Quick Reference: Optimization Priority
If you’re short on time, do these in order:
- Switch to Paper or Purpur (biggest single improvement)
- Lower view-distance and simulation-distance
- Apply Aikar’s JVM flags
- Pre-generate your world with Chunky
- Tune entity activation ranges in Paper config
- Profile with Spark and address top CPU consumers
- Optimize hopper and mob farm behavior
Each step builds on the last. Don’t skip to step 6 if you haven’t done steps 1-3. The basics matter more than fine-tuning.
On Witchly, our servers run on high-clock-speed dedicated hardware, giving you the best possible foundation for optimization. You can monitor TPS, resource usage, and performance metrics through your dashboard. But no amount of hardware can compensate for an unoptimized server — these configuration changes are what turn good hardware into great performance.